做个项目需要用到DataGridView,这个控件还是挺好用的,但是今天却发现无法实现自己想要的功能。主要是DataGridViewCheckBoxColumn这个列虽然是提供了复选框,但是却未能在复选框的旁边提供文本的显示。在网上搜索了一下,提供的方法很多都是弄两列,然后合并单元格,将两列合并成为了一列。不过我不太喜欢那种方式,于是就自己重写了一下DataGridViewColumn,略显简陋,只实现了最基本的功能,现在拿出来,希望各位能够提一些好的意见和见解。
首先定义一个实现了 IDataGridViewEditingControl 接口的类
class DataGridViewCheckBoxTextControl : CheckBox, IDataGridViewEditingControl
{
///
/// 当前所在表格
///
private DataGridView MyDataGridView { set; get; }
///
/// 值是否发生更改
///
private bool ValueChanged { set; get; }
///
/// 当前所在行
///
private int RowIndex { set; get; }
protected override void OnCheckedChanged(EventArgs e)
{
ValueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnCheckedChanged(e);
}
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
Font = dataGridViewCellStyle.Font;
ForeColor = dataGridViewCellStyle.ForeColor;
BackColor = dataGridViewCellStyle.BackColor;
}
public DataGridView EditingControlDataGridView
{
get
{
return MyDataGridView;
}
set
{
MyDataGridView = value;
}
}
public object EditingControlFormattedValue
{
get
{
return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
}
set
{
Checked = value == null ? false : (bool)value;
}
}
public int EditingControlRowIndex
{
get
{
return RowIndex;
}
set
{
RowIndex = value;
}
}
public bool EditingControlValueChanged
{
get
{
return ValueChanged;
}
set
{
ValueChanged = value;
}
}
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
switch (keyData & Keys.KeyCode)
{
case Keys.LButton:
return !dataGridViewWantsInputKey;
}
return !dataGridViewWantsInputKey;
}
public Cursor EditingPanelCursor
{
get { return Cursors.Default; }
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return this.Checked;
}
public void PrepareEditingControlForEdit(bool selectAll)
{
}
public bool RepositionEditingControlOnValueChange
{
get { return false; }
}
}
其次定义重写这个列所需要的单元格
public class DataGridViewCheckBoxTextCell : DataGridViewCell
{
public DataGridViewCheckBoxTextCell() : base() { }
private static Type defaultEditType = typeof(DataGridViewCheckBoxTextControl);
private static Type defaultValueType = typeof(System.Boolean);
public override Type EditType
{
get { return defaultEditType; }
}
///
/// 单元格边框颜色
///
private Color CellBorderColor { get { return Color.FromArgb(172, 168, 153); } }
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
var check = (Boolean)value;
if (paintParts == DataGridViewPaintParts.Background || paintParts == DataGridViewPaintParts.All)
{
graphics.FillRectangle(new SolidBrush(cellStyle.BackColor), cellBounds);
}
if (paintParts == DataGridViewPaintParts.Border || paintParts == DataGridViewPaintParts.All)
{
graphics.DrawRectangle(new Pen(CellBorderColor), cellBounds);
}
if (paintParts == DataGridViewPaintParts.SelectionBackground || Selected)
{
graphics.FillRectangle(new SolidBrush(cellStyle.SelectionBackColor), cellBounds);
}
var col = OwningColumn as DataGridViewCheckBoxTextColumn;
if (col != null && !string.IsNullOrEmpty(col.Text))
{
graphics.DrawString(col.Text, cellStyle.Font, new SolidBrush(Selected ?
cellStyle.SelectionForeColor : cellStyle.ForeColor),
new Point(cellBounds.X + 25, cellBounds.Y + cellBounds.Height / 4));
}
CheckBoxRenderer.DrawCheckBox(graphics, new Point(cellBounds.X + 4, cellBounds.Y + cellBounds.Height / 4), CheckState);
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
///
///
/// 当前复选框的状态
///
private CheckBoxState CheckState { set; get; }
protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)
{
var check = (bool)Value;
CheckState = check ? CheckBoxState.CheckedPressed : CheckBoxState.UncheckedPressed;
base.OnMouseDown(e);
}
protected override void OnMouseUp(DataGridViewCellMouseEventArgs e)
{
var check = (bool)Value;
Value = !check;
SetValue(RowIndex, Value);
CheckState = check ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
base.OnMouseUp(e);
}
public override Type ValueType
{
get
{
Type valueType = base.ValueType;
if (valueType != null)
{
return valueType;
}
return defaultValueType;
}
}
public override object DefaultNewRowValue
{
get
{
return true;
}
}
}
最后才需要再定义这个新建的列
public class DataGridViewCheckBoxTextColumn : DataGridViewColumn
{
public DataGridViewCheckBoxTextColumn()
: base()
{
CellTemplate = new DataGridViewCheckBoxTextCell();
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
if (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewCheckBoxTextCell)))
{
throw new Exception("这个列里面必须绑定MyDataGridViewCheckBoxCell");
}
base.CellTemplate = value;
}
}
public override object Clone()
{
DataGridViewCheckBoxTextColumn col = (DataGridViewCheckBoxTextColumn)base.Clone();
col.Text = Text;
return col;
}
public string Text { set; get; }
}
如果这个列是定义在控件类库内,那么引用到项目里面的时候,就能够直接在编辑器内添加这个列。如图:
最终效果图:
转载网址:https://www.cnblogs.com/rogation/p/3991097.html