转自生命体验博客
这几年都在web项目上工作和学习,windows的项目也只是windows服务,界面上的学习少了。这几天看了看DataGridView,跟.net1.1的差别还是很大。实现自定义单元格编辑类的方式也不同了。主要是通过实现自己的DataGridViewColumn
微软有一篇文章
如何:在 Windows 窗体 DataGridView 单元格中承载控件
主要几步:
1。创建自己的DataGridViewColumn,重写
public
override
DataGridViewCell CellTemplate
{
get ;
set ;
}
{
get ;
set ;
}
2.创建自己的DataGridViewCell,用作上面的类返回的DataGridViewCell。重写
public
override
Type EditType
{
get ;
}
public override Type ValueType
{
get ;
}
{
get ;
}
public override Type ValueType
{
get ;
}
3.创建自己的EditType,该类需要实现System.Windows.Forms.IDataGridViewEditingControl接口
class
DataGridViewDecimalTextBoxEditingControl : TextBox, IDataGridViewEditingControl
{
// ...一般让EditingControl继承自现有的控件或自己编写的windows自定义控件。
}
{
// ...一般让EditingControl继承自现有的控件或自己编写的windows自定义控件。
}
以下是一个完整的例子
public
class
DataGridViewMoneyTextBoxColumn : DataGridViewTextBoxColumn
{
public DataGridViewMoneyTextBoxColumn()
{
this .CellTemplate = new DataGridViewMoneyCell();
}
public override DataGridViewCell CellTemplate
{
get
{
return base .CellTemplate;
}
set
{
DataGridViewMoneyCell cell = value as DataGridViewMoneyCell;
if (value != null && cell == null )
{
throw new InvalidCastException( " Value provided for CellTemplate must be of type TEditNumDataGridViewCell or derive from it. " );
}
base .CellTemplate = value;
}
}
}
public class DataGridViewMoneyCell : DataGridViewTextBoxCell
{
public DataGridViewMoneyCell()
{
}
int decimalLength;
private static Type defaultEditType = typeof (MoneyTextBoxDataGridViewEditingControl);
private static Type defaultValueType = typeof (System.Decimal);
public int DecimalLength
{
get { return decimalLength; }
set { decimalLength = value; }
}
public override Type EditType
{
get { return defaultEditType; }
}
public override Type ValueType
{
get
{
Type valueType = base .ValueType;
if (valueType != null )
{
return valueType;
}
return defaultValueType;
}
}
}
public class MoneyTextBoxDataGridViewEditingControl : TextBox, IDataGridViewEditingControl
{
private DataGridView dataGridView; // grid owning this editing control
private bool valueChanged; // editing control's value has changed or not
private int rowIndex; // row index in which the editing control resides
#region IDataGridViewEditingControl 成员
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
this .Font = dataGridViewCellStyle.Font;
if (dataGridViewCellStyle.BackColor.A < 255 )
{
// The NumericUpDown control does not support transparent back colors
Color opaqueBackColor = Color.FromArgb( 255 , dataGridViewCellStyle.BackColor);
this .BackColor = opaqueBackColor;
this .dataGridView.EditingPanel.BackColor = opaqueBackColor;
}
else
{
this .BackColor = dataGridViewCellStyle.BackColor;
}
this .ForeColor = dataGridViewCellStyle.ForeColor;
}
public DataGridView EditingControlDataGridView
{
get
{
return this .dataGridView;
}
set
{
this .dataGridView = value;
}
}
public object EditingControlFormattedValue
{
get
{
return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
}
set
{
this .Text = ( string )value;
}
}
public int EditingControlRowIndex
{
get
{
return this .rowIndex;
}
set
{
this .rowIndex = value;
}
}
public bool EditingControlValueChanged
{
get { return this .valueChanged; }
set { this .valueChanged = value; }
}
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
switch (keyData & Keys.KeyCode)
{
case Keys.Right:
case Keys.Left:
case Keys.Down:
case Keys.Up:
case Keys.Home:
case Keys.End:
case Keys.Delete:
return true ;
}
return ! dataGridViewWantsInputKey;
}
public Cursor EditingPanelCursor
{
get { return Cursors.Default; }
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return this .Text;
}
public void PrepareEditingControlForEdit( bool selectAll)
{
if (selectAll)
{
this .SelectAll();
}
else
{
this .SelectionStart = this .Text.Length;
}
}
public bool RepositionEditingControlOnValueChange
{
get { return false ; }
}
#endregion
}
{
public DataGridViewMoneyTextBoxColumn()
{
this .CellTemplate = new DataGridViewMoneyCell();
}
public override DataGridViewCell CellTemplate
{
get
{
return base .CellTemplate;
}
set
{
DataGridViewMoneyCell cell = value as DataGridViewMoneyCell;
if (value != null && cell == null )
{
throw new InvalidCastException( " Value provided for CellTemplate must be of type TEditNumDataGridViewCell or derive from it. " );
}
base .CellTemplate = value;
}
}
}
public class DataGridViewMoneyCell : DataGridViewTextBoxCell
{
public DataGridViewMoneyCell()
{
}
int decimalLength;
private static Type defaultEditType = typeof (MoneyTextBoxDataGridViewEditingControl);
private static Type defaultValueType = typeof (System.Decimal);
public int DecimalLength
{
get { return decimalLength; }
set { decimalLength = value; }
}
public override Type EditType
{
get { return defaultEditType; }
}
public override Type ValueType
{
get
{
Type valueType = base .ValueType;
if (valueType != null )
{
return valueType;
}
return defaultValueType;
}
}
}
public class MoneyTextBoxDataGridViewEditingControl : TextBox, IDataGridViewEditingControl
{
private DataGridView dataGridView; // grid owning this editing control
private bool valueChanged; // editing control's value has changed or not
private int rowIndex; // row index in which the editing control resides
#region IDataGridViewEditingControl 成员
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
this .Font = dataGridViewCellStyle.Font;
if (dataGridViewCellStyle.BackColor.A < 255 )
{
// The NumericUpDown control does not support transparent back colors
Color opaqueBackColor = Color.FromArgb( 255 , dataGridViewCellStyle.BackColor);
this .BackColor = opaqueBackColor;
this .dataGridView.EditingPanel.BackColor = opaqueBackColor;
}
else
{
this .BackColor = dataGridViewCellStyle.BackColor;
}
this .ForeColor = dataGridViewCellStyle.ForeColor;
}
public DataGridView EditingControlDataGridView
{
get
{
return this .dataGridView;
}
set
{
this .dataGridView = value;
}
}
public object EditingControlFormattedValue
{
get
{
return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
}
set
{
this .Text = ( string )value;
}
}
public int EditingControlRowIndex
{
get
{
return this .rowIndex;
}
set
{
this .rowIndex = value;
}
}
public bool EditingControlValueChanged
{
get { return this .valueChanged; }
set { this .valueChanged = value; }
}
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
switch (keyData & Keys.KeyCode)
{
case Keys.Right:
case Keys.Left:
case Keys.Down:
case Keys.Up:
case Keys.Home:
case Keys.End:
case Keys.Delete:
return true ;
}
return ! dataGridViewWantsInputKey;
}
public Cursor EditingPanelCursor
{
get { return Cursors.Default; }
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return this .Text;
}
public void PrepareEditingControlForEdit( bool selectAll)
{
if (selectAll)
{
this .SelectAll();
}
else
{
this .SelectionStart = this .Text.Length;
}
}
public bool RepositionEditingControlOnValueChange
{
get { return false ; }
}
#endregion
}
生成项目,如果是控件类库,引用到你的windows程序里,你就能从DataGridView编辑列里找到我们定义的DataGridViewColumn:DataGridViewTextBoxColumn
直白的说,就是第一步定义类把第二步的Cell类暴露给DataGridView,第二步的Cell类把我自己希望的编辑的控件暴露给DataGridView,当Cell被选中并处于编辑状态时,我们定义的控件就会被创建并显示给用户。