C# 在Winform中,如何正确设置DataGridViewCheckBoxCell只读标志并将方形框绘制为灰色?
如何正确设置DataGridViewCheckBoxCell.ReadOnly属性并将其绘制为灰色?原始的DataGridCheckBoxCell不这样做 MyC# 在Winform中,如何正确设置DataGridViewCheckBoxCell只读标志并将方形框绘制为灰色?,c#,.net,winforms,datagridview,C#,.net,Winforms,Datagridview,如何正确设置DataGridViewCheckBoxCell.ReadOnly属性并将其绘制为灰色?原始的DataGridCheckBoxCell不这样做 MyDataGridView的数据来自BindingSource。加载数据后,我将特定单元格设置为只读 然而,实验表明它使其他单元格的ReadOnly属性不一致。大量调试会话显示,有时同一列中的其他单元格会重新实例化,从而重置其只读标志。这会导致单元格的绘制不一致 下面是一个工作示例应用程序的代码。它有4行。但是,如果在单元格的构造函数上设置
DataGridView
的数据来自BindingSource
。加载数据后,我将特定单元格设置为只读
然而,实验表明它使其他单元格的ReadOnly属性不一致。大量调试会话显示,有时同一列中的其他单元格会重新实例化,从而重置其只读标志。这会导致单元格的绘制不一致
下面是一个工作示例应用程序的代码。它有4行。但是,如果在单元格的构造函数上设置断点,您将看到它被实例化了4次以上。单击该复选框时,有时还会看到单元格重新实例化。这真让我困惑
我正在运行.NET3.5
Form1.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace DataGridPaintingIssue
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
estimateLineBindingSource.DataSource = createMockData();
this.Load += Form_Load;
}
private void Form_Load(object sender, EventArgs eventArgs)
{
setReadOnly();
}
private List<EstimateLineNet> createMockData()
{
var result = new List<EstimateLineNet>()
{
new EstimateLineNet("*", false, "HEADER"),
new EstimateLineNet(null, false, "Child"),
new EstimateLineNet(null, true, "openitem"),
new EstimateLineNet(null, false, "Child3"),
};
return result;
}
private void setReadOnly()
{
estimateGridView.Rows[1].Cells[2].ReadOnly = true; //manually set a specific cell's ReadOnly flag.
}
}
public class OpenItemCheckBoxColumn : DataGridViewCheckBoxColumn
{
public OpenItemCheckBoxColumn()
{
init();
}
private void init()
{
CellTemplate = new OpenItemCheckBoxCell();
}
public class OpenItemCheckBoxCell : DataGridViewCheckBoxCell
{
public OpenItemCheckBoxCell()
{
;//breakpoint shows sometimes the cell reinstantiates.
}
private DataGridViewElementStates _lastState;
private bool _lastReadOnly;
protected override void Paint(
Graphics graphics,
Rectangle clipBounds,
Rectangle cellBounds,
int rowIndex,
DataGridViewElementStates elementState,
object value,
object formattedValue,
string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
//breakpoint with condition _lastState != elementState shows the ReadOnly flag resets to false
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText,
cellStyle, advancedBorderStyle, paintParts);
_lastState = elementState;
_lastReadOnly = ReadOnly; //need to persist this ReadOnly flag.
}
}
}
public class EstimateLineNet
{
public EstimateLineNet(string asterisk, bool openItem, string description)
{
Asterisk = asterisk;
OpenItem = openItem;
Description = description;
}
public string Asterisk { get; set; }
public bool OpenItem { get; set; }
public string Description { get; set; }
}
}
namespace DataGridPaintingIssue
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.estimateGridView = new System.Windows.Forms.DataGridView();
this.Asterisk = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.OpenItem = new DataGridPaintingIssue.OpenItemCheckBoxColumn();
this.Desc = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.estimateLineBindingSource = new System.Windows.Forms.BindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.estimateGridView)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.estimateLineBindingSource)).BeginInit();
this.SuspendLayout();
//
// estimateGridView
//
this.estimateGridView.AllowUserToAddRows = false;
this.estimateGridView.AllowUserToDeleteRows = false;
this.estimateGridView.AllowUserToResizeRows = false;
this.estimateGridView.AutoGenerateColumns = false;
this.estimateGridView.ColumnHeadersHeight = 19;
this.estimateGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
this.estimateGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Asterisk,
this.OpenItem,
this.Desc});
this.estimateGridView.DataSource = this.estimateLineBindingSource;
this.estimateGridView.Dock = System.Windows.Forms.DockStyle.Fill;
this.estimateGridView.Location = new System.Drawing.Point(0, 0);
this.estimateGridView.Name = "estimateGridView";
this.estimateGridView.Size = new System.Drawing.Size(284, 261);
this.estimateGridView.TabIndex = 0;
//
// Asterisk
//
this.Asterisk.DataPropertyName = "Asterisk";
this.Asterisk.HeaderText = "*";
this.Asterisk.MaxInputLength = 2;
this.Asterisk.Name = "Asterisk";
this.Asterisk.Width = 20;
//
// OpenItem
//
this.OpenItem.DataPropertyName = "OpenItem";
this.OpenItem.HeaderText = "O";
this.OpenItem.Name = "OpenItem";
this.OpenItem.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.OpenItem.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
this.OpenItem.Width = 30;
//
// Desc
//
this.Desc.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.Desc.DataPropertyName = "Description";
this.Desc.HeaderText = "Description";
this.Desc.MaxInputLength = 60;
this.Desc.Name = "Desc";
//
// estimateLineBindingSource
//
this.estimateLineBindingSource.DataSource = typeof(DataGridPaintingIssue.EstimateLineNet);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Controls.Add(this.estimateGridView);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.estimateGridView)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.estimateLineBindingSource)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridViewTextBoxColumn Asterisk;
private OpenItemCheckBoxColumn OpenItem;
private System.Windows.Forms.DataGridViewTextBoxColumn Desc;
private System.Windows.Forms.DataGridView estimateGridView;
private System.Windows.Forms.BindingSource estimateLineBindingSource;
}
}
使用系统;
使用System.Collections.Generic;
使用系统图;
使用System.Windows.Forms;
命名空间DataGridPaintingIssue
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
estimateLineBindingSource.DataSource=createMockData();
此.Load+=形式荷载;
}
私有无效表单加载(对象发送方,EventArgs EventArgs)
{
setReadOnly();
}
私有列表createMockData()
{
var result=新列表()
{
新估算线网(“*”,假,“标头”),
新的EstimateLineNet(空,假,“子”),
新的EstimateLineNet(null,true,“openitem”),
新EstimateLineNet(空,假,“Child3”),
};
返回结果;
}
私有void setReadOnly()
{
estimateGridView.Rows[1]。单元格[2]。ReadOnly=true;//手动设置特定单元格的只读标志。
}
}
公共类OpenItemCheckBoxColumn:DataGridViewCheckBoxColumn
{
公共OpenItemCheckBoxColumn()
{
init();
}
私有void init()
{
CellTemplate=新建OpenItemCheckBoxCell();
}
公共类OpenItemCheckBoxCell:DataGridViewCheckBoxCell
{
公共OpenItemCheckBoxCell()
{
;//断点有时显示单元格重新实例化。
}
私有DataGridViewElementState_lastState;
私人布尔(lastReadOnly);
保护覆盖无效涂料(
图形,
矩形剪贴簿,
矩形单元格边界,
整数行索引,
DataGridViewElementState元素状态,
对象值,
对象格式化值,
字符串错误文本,
DataGridViewCellStyle单元样式,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts(喷漆零件)
{
//条件为_lastState!=elementState的断点显示只读标志重置为false
绘制(图形、剪贴簿、单元格边界、行索引、元素状态、值、格式化值、错误文本、,
cellStyle、advancedBorderStyle、paintParts);
_lastState=elementState;
_lastReadOnly=ReadOnly;//需要保留此只读标志。
}
}
}
公共类估算线网
{
公共估计LineNet(字符串星号、bool openItem、字符串描述)
{
星号=星号;
OpenItem=OpenItem;
描述=描述;
}
公共字符串星号{get;set;}
公共bool OpenItem{get;set;}
公共字符串说明{get;set;}
}
}
Form1.Designer.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace DataGridPaintingIssue
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
estimateLineBindingSource.DataSource = createMockData();
this.Load += Form_Load;
}
private void Form_Load(object sender, EventArgs eventArgs)
{
setReadOnly();
}
private List<EstimateLineNet> createMockData()
{
var result = new List<EstimateLineNet>()
{
new EstimateLineNet("*", false, "HEADER"),
new EstimateLineNet(null, false, "Child"),
new EstimateLineNet(null, true, "openitem"),
new EstimateLineNet(null, false, "Child3"),
};
return result;
}
private void setReadOnly()
{
estimateGridView.Rows[1].Cells[2].ReadOnly = true; //manually set a specific cell's ReadOnly flag.
}
}
public class OpenItemCheckBoxColumn : DataGridViewCheckBoxColumn
{
public OpenItemCheckBoxColumn()
{
init();
}
private void init()
{
CellTemplate = new OpenItemCheckBoxCell();
}
public class OpenItemCheckBoxCell : DataGridViewCheckBoxCell
{
public OpenItemCheckBoxCell()
{
;//breakpoint shows sometimes the cell reinstantiates.
}
private DataGridViewElementStates _lastState;
private bool _lastReadOnly;
protected override void Paint(
Graphics graphics,
Rectangle clipBounds,
Rectangle cellBounds,
int rowIndex,
DataGridViewElementStates elementState,
object value,
object formattedValue,
string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
//breakpoint with condition _lastState != elementState shows the ReadOnly flag resets to false
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText,
cellStyle, advancedBorderStyle, paintParts);
_lastState = elementState;
_lastReadOnly = ReadOnly; //need to persist this ReadOnly flag.
}
}
}
public class EstimateLineNet
{
public EstimateLineNet(string asterisk, bool openItem, string description)
{
Asterisk = asterisk;
OpenItem = openItem;
Description = description;
}
public string Asterisk { get; set; }
public bool OpenItem { get; set; }
public string Description { get; set; }
}
}
namespace DataGridPaintingIssue
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.estimateGridView = new System.Windows.Forms.DataGridView();
this.Asterisk = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.OpenItem = new DataGridPaintingIssue.OpenItemCheckBoxColumn();
this.Desc = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.estimateLineBindingSource = new System.Windows.Forms.BindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.estimateGridView)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.estimateLineBindingSource)).BeginInit();
this.SuspendLayout();
//
// estimateGridView
//
this.estimateGridView.AllowUserToAddRows = false;
this.estimateGridView.AllowUserToDeleteRows = false;
this.estimateGridView.AllowUserToResizeRows = false;
this.estimateGridView.AutoGenerateColumns = false;
this.estimateGridView.ColumnHeadersHeight = 19;
this.estimateGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
this.estimateGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Asterisk,
this.OpenItem,
this.Desc});
this.estimateGridView.DataSource = this.estimateLineBindingSource;
this.estimateGridView.Dock = System.Windows.Forms.DockStyle.Fill;
this.estimateGridView.Location = new System.Drawing.Point(0, 0);
this.estimateGridView.Name = "estimateGridView";
this.estimateGridView.Size = new System.Drawing.Size(284, 261);
this.estimateGridView.TabIndex = 0;
//
// Asterisk
//
this.Asterisk.DataPropertyName = "Asterisk";
this.Asterisk.HeaderText = "*";
this.Asterisk.MaxInputLength = 2;
this.Asterisk.Name = "Asterisk";
this.Asterisk.Width = 20;
//
// OpenItem
//
this.OpenItem.DataPropertyName = "OpenItem";
this.OpenItem.HeaderText = "O";
this.OpenItem.Name = "OpenItem";
this.OpenItem.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.OpenItem.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
this.OpenItem.Width = 30;
//
// Desc
//
this.Desc.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.Desc.DataPropertyName = "Description";
this.Desc.HeaderText = "Description";
this.Desc.MaxInputLength = 60;
this.Desc.Name = "Desc";
//
// estimateLineBindingSource
//
this.estimateLineBindingSource.DataSource = typeof(DataGridPaintingIssue.EstimateLineNet);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Controls.Add(this.estimateGridView);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.estimateGridView)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.estimateLineBindingSource)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridViewTextBoxColumn Asterisk;
private OpenItemCheckBoxColumn OpenItem;
private System.Windows.Forms.DataGridViewTextBoxColumn Desc;
private System.Windows.Forms.DataGridView estimateGridView;
private System.Windows.Forms.BindingSource estimateLineBindingSource;
}
}
命名空间DataGridPaintingIssue
{
部分类Form1
{
///
///必需的设计器变量。
///
private System.ComponentModel.IContainer components=null;
///
///清理所有正在使用的资源。
///
///如果应释放托管资源,则为true;否则为false。
受保护的覆盖无效处置(布尔处置)
{
if(处理和(组件!=null))
{
组件。Dispose();
}
基地。处置(处置);
}
#区域Windows窗体设计器生成的代码
///
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
///
私有void InitializeComponent()
{
this.components=new System.ComponentModel.Container();
this.estimateGridView=new System.Windows.Forms.DataGridView();
this.Asterisk=new System.Windows.Forms.DataGridViewTextBoxColumn();
this.OpenItem=新的DataGridPaintingIssue.OpenItemCheckBoxColumn();
this.Desc=new System.Windows.Forms.DataGridViewTextBoxColumn();
this.estimateLineBindingSource=new System.Windows.Forms.BindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.estimateGridView)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.estimateLineBindingSource)).BeginInit();
这个.SuspendLayout();
//
//估计网格视图
//
this.estimateGridView.AllowUserToAddress=false;
this.estimateGridView.AllowUserToDeleteRows=false;
this.estimateGridView.AllowUserStoreSizeRows=false;
this.estimateGridView.AutoGenerateColumns=false;
this.estimateGridView.ColumnHeaderShight=19;
this.estimateGridView.ReadOnly = true;
this.Asterisk.ReadOnly = true;
this.OpenItem.ReadOnly = true;
this.Desc.ReadOnly = true;
private void setReadOnly()
{
estimateGridView.Rows[1].Cells[1].ReadOnly = true;
}