因DataGridView的单元格需要显示复杂的内容,所以打算自己创建一个列继承DataGridViewColumn
再创建类继承DataGridViewCell,和IDataGridViewEditingControl。但是实际展示出来的效果,却是一片空白。
我给DataGridView设置双缓冲后,单元格变得一片漆黑
(图片仅为测试,到时候放的是自定义控件而不是CheckBox)
以下是完整代码
public class 自定义列 : DataGridViewColumn {
public 自定义列() : base (new 自定义单元格()) { }
/// <summary>
/// 获取或设置用于创建新单元格的模板。
/// </summary>
public override DataGridViewCell CellTemplate {
get {
return base.CellTemplate;
}
set {
base.CellTemplate = value;
}
}
}
public class 自定义单元格 : DataGridViewCell {
public 自定义单元格() : base() { }
// <summary>
/// 初始化用于编辑单元格的控件。
/// </summary>
/// <param name="rowIndex">单元格所在位置的从零开始的行索引。</param>
/// <param name="initialFormattedValue">它表示在开始编辑时单元格显示的值。</param>
/// <param name="dataGridViewCellStyle">表示单元格样式的 System.Windows.Forms.DataGridViewCellStyle。</param>
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) {
自定义编辑控件 ctl = (自定义编辑控件)DataGridView.EditingControl;
if (Value != null && Value != System.DBNull.Value) {
ctl.Checked = (bool)Value;
}
//初始化之后设置编辑状态的值
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
}
/// <summary>
/// 获取单元格的寄宿编辑控件的类型。
/// </summary>
public override Type EditType {
get {
return typeof(自定义编辑控件);
}
}
/// <summary>
/// 获取或设置单元格中值的数据类型。
/// </summary>
public override Type ValueType {
get {
return typeof(bool);
}
}
/// <summary>
/// 获取新记录所在行中单元格的默认值。
/// </summary>
public override object DefaultNewRowValue {
get {
return false;
}
}
}
public class 自定义编辑控件 : CheckBox, IDataGridViewEditingControl {
public CheckBox Box;
public DataGridView 关联表格;
public int 行下标;
public bool 是否被更改;
public 自定义编辑控件() {
Box = this;
}
/// <summary>
/// 更改控件的用户界面 (UI),使之与指定单元格样式一致。
/// </summary>
/// <param name="dataGridViewCellStyle">要用作用户界面的模型的 System.Windows.Forms.DataGridViewCellStyle。</param>
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle) {
this.Font = dataGridViewCellStyle.Font;
Box.ForeColor = dataGridViewCellStyle.ForeColor;
Box.BackColor = dataGridViewCellStyle.BackColor;
}
/// <summary>
/// 确定指定的键是应由编辑控件处理的常规输入键,还是应由 System.Windows.Forms.DataGridView 处理的特殊键。
/// </summary>
/// <param name="key">一个 System.Windows.Forms.Keys,表示按下的键。</param>
/// <param name="dataGridViewWantsInputKey">当 System.Windows.Forms.DataGridView 要处理 keyData 中的 System.Windows.Forms.Keys时,则为 true;否则为 false。</param>
/// <returns>如果指定的键是应由编辑控件处理的常规输入键,则为 true;否则为 false。</returns>
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) {
switch (keyData & Keys.KeyCode) //设置方向键等都不令其进入编辑状态
{
case Keys.Left:
case Keys.Up:
case Keys.Down:
case Keys.Right:
case Keys.Home:
case Keys.End:
case Keys.PageDown:
case Keys.PageUp:
return true;
default:
return false;
}
}
/// <summary>
/// 检索单元格的格式化值。
/// </summary>
/// <param name="context">System.Windows.Forms.DataGridViewDataErrorContexts 值的按位组合,它指定需要数据的上下文。</param>
/// <returns>一个 System.Object,表示单元格内容的格式化版本。</returns>
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context) {
return EditingControlFormattedValue;
}
/// <summary>
/// 准备当前选中的单元格以进行编辑。
/// </summary>
/// <param name="selectAll">为 true,则选择单元格的全部内容;否则为 false。</param>
public void PrepareEditingControlForEdit(bool selectAll) {
}
/// <summary>
/// 获取或设置包含单元格的 System.Windows.Forms.DataGridView。
/// </summary>
public DataGridView EditingControlDataGridView {
get {
return 关联表格;
}
set {
关联表格 = value;
}
}
/// <summary>
/// 默认格式化值
/// 实现接口 IDataGridViewEditingControl.EditingControlFormattedValue
/// </summary>
public object EditingControlFormattedValue {
get { return Box.Checked; }
set { Box.Checked = (bool)value; }
}
/// <summary>
/// 获取或设置该承载单元格的父行的索引。包含该单元格的行的索引,如果没有父行,则为 -1。
/// </summary>
public int EditingControlRowIndex {
get {
return 行下标;
}
set {
行下标 = value;
}
}
/// <summary>
/// 获取或设置一个值,该值指示编辑控件的值是否与承载单元格的值不同。
/// </summary>
public bool EditingControlValueChanged {
get {
return 是否被更改;
}
set {
是否被更改 = value;
}
}
/// <summary>
/// 获取当鼠标指针位于 System.Windows.Forms.DataGridView.EditingPanel 上方但不位于编辑控件上方时所使用的光标。
/// </summary>
public Cursor EditingPanelCursor {
get {
return base.Cursor;
}
}
/// <summary>
/// 获取或设置一个值,该值指示每当值更改时,是否需要重新定位单元格的内容。
/// </summary>
public bool RepositionEditingControlOnValueChange {
get {
return false;
}
}
/// <summary>
/// 值修改时通知datagridviewCell.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void uiSwitch_ActiveChanged(object sender, EventArgs e) {
//DataGridView中Cell的Changed事件
EditingControlDataGridView.NotifyCurrentCellDirty(true);
}
}
Form窗体里:创建一个表格设置好列
public Form1() {
InitializeComponent();
//给表格设置双缓冲,发现变黑色
Type dgvType = this.dataGridView1.GetType();
PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(this.dataGridView1, true, null);
}
private void WinForm_Load(object sender, EventArgs e) {
DataTable dt = new DataTable();
dt.Columns.Add("名称");
dt.Columns.Add("布尔");
DataRow dr1 = dt.NewRow();
dr1[0] = "测试1";
dr1[1] = true;
dt.Rows.Add(dr1);
dataGridView1.DataSource = dt;
}
private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) {
}
Form的设计器代码
/// <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 Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent() {
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column2 = new TestForm.自定义列();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.AllowUserToResizeColumns = false;
this.dataGridView1.AllowUserToResizeRows = false;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column1,
this.Column2});
this.dataGridView1.Location = new System.Drawing.Point(78, 176);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowTemplate.Height = 23;
this.dataGridView1.Size = new System.Drawing.Size(434, 246);
this.dataGridView1.TabIndex = 0;
this.dataGridView1.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(this.dataGridView1_DataError);
//
// Column1
//
this.Column1.DataPropertyName = "名称";
this.Column1.HeaderText = "名称";
this.Column1.Name = "Column1";
//
// Column2
//
this.Column2.DataPropertyName = "布尔";
this.Column2.HeaderText = "布尔";
this.Column2.Name = "Column2";
//
// WinForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.dataGridView1);
this.Name = "WinForm";
this.Text = "Form1";
this.Load += new System.EventHandler(this.WinForm_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
private 自定义列 Column2;