如何实现设计时不可删除的DataGridView首列复选框列?
自定义DataGridView固定首列复选框的设计器实现方案
一、实现设计器中显示固定复选框列
可以在设计器中显示该复选框列,但不能仅通过构造函数添加——这种方式会让列被设计器序列化,用户可随意修改删除。要实现固定首列且设计器可见,需结合构造函数初始化+列状态校验逻辑:
public class CheckBoxFirstDataGridView : DataGridView { private readonly DataGridViewCheckBoxColumn _fixedCheckBoxColumn; public CheckBoxFirstDataGridView() { // 初始化固定复选框列 _fixedCheckBoxColumn = new DataGridViewCheckBoxColumn { Name = "FixedSelectColumn", HeaderText = "", Width = 30, ReadOnly = false, DisplayIndex = 0 }; base.Columns.Insert(0, _fixedCheckBoxColumn); } }
二、阻止用户修改/删除该复选框列
要彻底锁定该列,需从列操作拦截、序列化控制、设计器编辑器过滤三个层面入手:
1. 拦截列移除/移动操作
重写DataGridView的列事件,确保固定列无法被删除或移位:
protected override void OnColumnRemoved(DataGridViewColumnEventArgs e) { // 若删除的是固定复选框列,立即恢复 if (e.Column == _fixedCheckBoxColumn) { base.Columns.Insert(0, _fixedCheckBoxColumn); return; } base.OnColumnRemoved(e); } protected override void OnColumnAdded(DataGridViewColumnEventArgs e) { base.OnColumnAdded(e); // 确保固定列始终在第一位 if (_fixedCheckBoxColumn.DisplayIndex != 0) { _fixedCheckBoxColumn.DisplayIndex = 0; } } public new DataGridViewColumnCollection Columns { get { // 每次访问列集合时,校验固定列状态 if (!base.Columns.Contains(_fixedCheckBoxColumn.Name)) { base.Columns.Insert(0, _fixedCheckBoxColumn); } else if (_fixedCheckBoxColumn.DisplayIndex != 0) { _fixedCheckBoxColumn.DisplayIndex = 0; } return base.Columns; } }
2. 禁止设计器序列化固定列
通过特性标记,让设计器不保存固定列的配置,避免用户修改被持久化:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public DataGridViewCheckBoxColumn FixedSelectColumn { get => _fixedCheckBoxColumn; }
3. 自定义设计器编辑器隐藏固定列
让用户打开列集合编辑器时看不到固定列,从根源避免误操作:
using System.Windows.Forms.Design; using System.ComponentModel; [Designer(typeof(CheckBoxFirstDataGridViewDesigner))] public class CheckBoxFirstDataGridView : DataGridView { // 原有代码... } public class CheckBoxFirstDataGridViewDesigner : DataGridViewDesigner { public override void Initialize(IComponent component) { base.Initialize(component); // 替换列集合编辑器为自定义版本 var columnsProp = TypeDescriptor.GetProperties(component)["Columns"]; if (columnsProp != null) { var editorAttr = new EditorAttribute(typeof(CustomColumnEditor), typeof(UITypeEditor)); var newProps = TypeDescriptor.CreateProperties(component.GetType(), new[] { editorAttr }); } } } public class CustomColumnEditor : ColumnCollectionEditor { public CustomColumnEditor(Type type) : base(type) { } protected override object[] GetItems(object editValue) { // 过滤掉固定复选框列,不让用户在编辑器中看到 var columns = base.GetItems(editValue) as DataGridViewColumn[]; return columns?.Where(col => col.Name != "FixedSelectColumn").ToArray(); } }
效果说明
通过上述方案,自定义DataGridView会:
- 在设计器和运行时始终显示首列复选框
- 用户无法通过列集合编辑器删除、修改该列
- 新添加的列自动排在固定列之后,无法抢占首位置
内容的提问来源于stack exchange,提问作者Piglet
相关产品推荐
相关产品推荐

