最近在做项目使用DataGridView控件时,想在编辑单元格时实现这样一个功能:编辑单元格是能显示textbox及一个按钮控件,既可以在textbox里编辑数据,也可以单button按钮弹出一个编辑器窗体来编辑字符串。由于DataGridView没有提供该类型的ColumnType,所以决定自定义一个。
自定义ColumnType需要分别从三个类中派生:IDataGridViewEditingControl,DataGridViewTextBoxCell,DataGridViewColumn。1、自定义一个控件实现IDataGridViewEditingControl接口。2、从DataGridViewTextBoxCell派一个类来调用刚才自定义的编辑控件。3、从DataGridViewColumn派生一个类来实现ColumnType,使之能够在DataGridView加载该类型列。
实现代码如下:
1、DataGridViewTextBoxButtonEditingControl.cs文件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace System.Windows.Forms
{
public partial class DataGridViewTextBoxButtonEditingControl : UserControl,IDataGridViewEditingControl
{
private static readonly DataGridViewContentAlignment anyCenter;
private static readonly DataGridViewContentAlignment anyRight;
private static readonly DataGridViewContentAlignment anyTop;
private DataGridView dataGridView;
private int rowIndex;
private bool valueChanged;
private bool repositionOnValueChanged;
public DataGridViewTextBoxButtonEditingControl()
{
InitializeComponent();
}
#region Implement the IDataGridViewEditingControl's Method and Property
/// <summary>
/// Implements the IDataGridViewEditingControl.EditingControlDataGridView property
/// </summary>
public DataGridView EditingControlDataGridView
{
get
{
return dataGridView;
}
set
{
dataGridView = value;
}
}
/// <summary>
/// Implements the IDataGridViewEditingControl.EditingControlFormattedValue.Property
/// </summary>
public object EditingControlFormattedValue
{
get
{
return Value;
}
set
{
this.Value = (string)value;
}
}
/// <summary>
/// Implement the IDataGridViewEditingControl.EditingCotrolRowIndex
/// </summary>
public int EditingControlRowIndex
{
get { return this.rowIndex; }
set { this.rowIndex = value; }
}
/// <summary>
/// Implement the IDataGridViewEditingControl.EditingControlValueChanged
/// </summary>
public bool EditingControlValueChanged
{
get { return this.valueChanged; }
set { this.valueChanged = value; }
}
/// <summary>
/// Implement the IDataGridViewEditingControl.EditingPanelCursor
/// </summary>
public Cursor EditingPanelCursor
{
get { return Cursors.Default; }
}
/// <summary>
/// Implement the IDataGridViewEditingControl.RepositionEditingControlOnValueChange
/// </summary>
public bool RepositionEditingControlOnValueChange
{
get { return this.repositionOnValueChanged; }
}
/// <summary>
/// Implement the IDataGridViewEditingControl.ApplyCellStyleToEditingControl
/// </summary>
/// <param name="dataGridViewCellStyle"></param>
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
this.txtEdit.Font = dataGridViewCellStyle.Font;
if (dataGridViewCellStyle.BackColor.A < 0xff)
{
Color color = Color.FromArgb(0xff, dataGridViewCellStyle.BackColor);
this.txtEdit.BackColor = color;
this.dataGridView.EditingPanel.BackColor = color;
}
else
{
this.txtEdit.BackColor = dataGridViewCellStyle.BackColor;
}
this.txtEdit.ForeColor = dataGridViewCellStyle.ForeColor;
if (dataGridViewCellStyle.WrapMode == DataGridViewTriState.True)
{
this.txtEdit.WordWrap = true;
}
this.repositionOnValueChanged = (dataGridViewCellStyle.WrapMode == DataGridViewTriState.True) && ((dataGridViewCellStyle.Alignment & anyTop) == DataGridViewContentAlignment.NotSet);
}
/// <summary>
/// Implement the IDataGridViewEditingControl.EditingControlWantsInputKey
/// </summary>
/// <param name="keyData"></param>
/// <param name="dataGridViewWantsInputKey"></param>
/// <returns></returns>
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
switch ((keyData & Keys.KeyCode))
{
case Keys.Prior:
case Keys.Next:
if (!this.valueChanged)
{
break;
}
return true;
case Keys.End:
case Keys.Home:
if (this.txtEdit.SelectionLength == this.txtEdit.Text.Length)
{
break;
}
return true;
case Keys.Left:
if (((this.txtEdit.RightToLeft != RightToLeft.No) || ((this.txtEdit.SelectionLength == 0))) && ((this.txtEdit.RightToLeft != RightToLeft.Yes) || ((this.txtEdit.SelectionLength == 0))))
{
break;
}
return true;
case Keys.Up:
if ((this.txtEdit.Text.IndexOf("/r/n") < 0) || ((this.txtEdit.SelectionLength) < this.txtEdit.Text.IndexOf("/r/n")))
{
break;
}
return true;
case Keys.Right:
if (((this.txtEdit.RightToLeft != RightToLeft.No) || ((this.txtEdit.SelectionLength == 0))) && ((this.txtEdit.RightToLeft != RightToLeft.Yes) || ((this.txtEdit.SelectionLength == 0))))
{
break;
}
return true;
case Keys.Down:
{
int startIndex = this.txtEdit.SelectionLength;
if (this.Text.IndexOf("/r/n", startIndex) == -1)
{
break;
}
return true;
}
case Keys.Delete:
if ((this.txtEdit.SelectionLength <= 0))
{
break;
}
return true;
case Keys.Return:
if ((((keyData & (Keys.Alt | Keys.Control | Keys.Shift)) == Keys.Shift) && this.txtEdit.Multiline))
{
return true;
}
break;
}
return !dataGridViewWantsInputKey;
}
/// <summary>
/// Implement the IDataGridViewEditingControl.GetEditingControlFormattedValue
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}
/// <summary>
/// Implement the IDataGridViewEditingControl.PrepareEditingControlForEdit
/// </summary>
/// <param name="selectAll"></param>
public void PrepareEditingControlForEdit(bool selectAll)
{
}
private static HorizontalAlignment TranslateAlignment(DataGridViewContentAlignment align)
{
if ((align & anyRight) != DataGridViewContentAlignment.NotSet)
{
return HorizontalAlignment.Right;
}
if ((align & anyCenter) != DataGridViewContentAlignment.NotSet)
{
return HorizontalAlignment.Center;
}
return HorizontalAlignment.Left;
}
#endregion
public string Value
{
get { return this.txtEdit.Text; }
set { this.txtEdit.Text = value; }
}
public int MaxLength
{
get { return this.txtEdit.MaxLength; }
set { this.txtEdit.MaxLength = value; }
}
public new BorderStyle BorderStyle
{
get { return this.txtEdit.BorderStyle; }
set { this.txtEdit.BorderStyle = value; }
}
private void btn_Click(object sender, EventArgs e)
{
EditForm frm = new EditForm(Value);
frm.ShowDialog();
if(!string.IsNullOrEmpty(frm.TextString))
Value = frm.TextString;
this.valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
}
private void txtEdit_TextChanged(object sender, EventArgs e)
{
}
private void txtEdit_Leave(object sender, EventArgs e)
{
Value = txtEdit.Text;
this.valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
}
}
}
2、DataGridViewTextBoxButtonEditingControl.Disgner.cs文件
namespace System.Windows.Forms
{
partial class DataGridViewTextBoxButtonEditingControl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.btn = new System.Windows.Forms.Button();
this.txtEdit = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// btn
//
this.btn.Dock = System.Windows.Forms.DockStyle.Right;
this.btn.Location = new System.Drawing.Point(298, 0);
this.btn.Name = "btn";
this.btn.Size = new System.Drawing.Size(23, 24);
this.btn.TabIndex = 1;
this.btn.Text = "…";
this.btn.UseVisualStyleBackColor = true;
this.btn.Click += new System.EventHandler(this.btn_Click);
//
// txtEdit
//
this.txtEdit.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.txtEdit.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtEdit.Location = new System.Drawing.Point(0, 0);
this.txtEdit.Multiline = false;
this.txtEdit.Name = "txtEdit";
this.txtEdit.Size = new System.Drawing.Size(298, 24);
this.txtEdit.TabIndex = 2;
this.txtEdit.Text = "";
this.txtEdit.Leave += new System.EventHandler(this.txtEdit_Leave);
this.txtEdit.TextChanged += new System.EventHandler(this.txtEdit_TextChanged);
//
// DataGridViewTextBoxButtonEditingControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.txtEdit);
this.Controls.Add(this.btn);
this.Name = "DataGridViewTextBoxButtonEditingControl";
this.Size = new System.Drawing.Size(321, 24);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btn;
private RichTextBox txtEdit;
}
}
3、DataGridViewTexBoxButtonCell.cs文件
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
namespace System.Windows.Forms
{
public class DataGridViewTexBoxButtonCell:DataGridViewTextBoxCell
{
public DataGridViewTexBoxButtonCell() : base()
{
}
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
DataGridViewTextBoxButtonEditingControl ctl = DataGridView.EditingControl as DataGridViewTextBoxButtonEditingControl;
if (this.Value != null)
ctl.Value = this.Value.ToString();
else
ctl.Value = string.Empty;
}
public override Type EditType
{
get
{
return typeof(DataGridViewTextBoxButtonEditingControl);
}
}
public override Type ValueType
{
get { return typeof(string); }
}
public override object DefaultNewRowValue
{
get
{
return string.Empty;
}
}
}
}
4、DataGridViewTexBoxButtonColumn.cs文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Globalization;
namespace System.Windows.Forms
{
public class DataGridViewTexBoxButtonColumn : DataGridViewColumn
{
public DataGridViewTexBoxButtonColumn()
: base(new DataGridViewTexBoxButtonCell())
{
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
if(value!=null && !value.GetType().IsAssignableFrom(typeof(DataGridViewTexBoxButtonCell)))
{
throw new InvalidCastException("Must be a DataGridViewTextBoxButtonCell");
}
base.CellTemplate=value;
}
}
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dwchenxj2005/archive/2008/10/19/3103958.aspx