Ext.Net Grid Panel复选框选择模型:初始选中后禁止取消勾选
解决Ext.Net GridPanel锁定初始选中行不可取消的问题
这个需求我之前处理过,Ext.Net的CheckboxSelectionModel在这类“部分行锁定选中状态”的场景里确实有容易踩的小坑,我给你两个经过验证的可行方案,完美适配你的需求:
方案一:通过事件拦截精准控制取消操作
核心思路是给需要锁定的行标记自定义属性,然后在取消选中的前置事件里做判断,只阻止锁定行的取消操作,其他行正常交互。
步骤1:后台给锁定行打标记
构造数据时,给需要锁定的行添加IsLocked字段,同时设置初始选中状态:
// 定义你的数据模型 public class GridRowModel { public int Id { get; set; } public string Name { get; set; } public bool IsLocked { get; set; } // 标记是否锁定选中状态 public bool Selected { get; set; } // 初始选中状态 } // 后台绑定数据并设置初始选中 var rowData = new List<GridRowModel> { new GridRowModel { Id = 1, Name = "默认选中且锁定", IsLocked = true, Selected = true }, new GridRowModel { Id = 2, Name = "可自由选择", IsLocked = false, Selected = false }, new GridRowModel { Id = 3, Name = "默认选中且锁定", IsLocked = true, Selected = true } }; // 绑定到Grid的Store gridPanel.GetStore().DataSource = rowData; gridPanel.GetStore().DataBind(); // 静默设置初始选中(避免触发取消事件) var selectionModel = gridPanel.GetSelectionModel() as CheckboxSelectionModel; foreach (var row in rowData.Where(r => r.Selected)) { var record = gridPanel.GetStore().GetById(row.Id); if (record != null) { selectionModel.Select(record, true); // 第二个参数true表示静默选中,不触发事件 } }
步骤2:前端配置BeforeDeselect事件
在CheckboxSelectionModel里配置事件,仅允许非锁定行取消选中:
<ext:GridPanel ID="gridPanel" runat="server"> <Store> <ext:Store runat="server"> <Model> <ext:Model runat="server" IDProperty="Id"> <Fields> <ext:ModelField Name="Id" /> <ext:ModelField Name="Name" /> <ext:ModelField Name="IsLocked" Type="Boolean" /> <ext:ModelField Name="Selected" Type="Boolean" /> </Fields> </ext:Model> </Model> </ext:Store> </Store> <ColumnModel runat="server"> <Columns> <ext:Column runat="server" Text="ID" DataIndex="Id" /> <ext:Column runat="server" Text="名称" DataIndex="Name" /> </Columns> </ColumnModel> <SelectionModel> <ext:CheckboxSelectionModel runat="server"> <Listeners> <!-- 仅非锁定行可取消选中 --> <BeforeDeselect Handler="return !record.data.IsLocked;" /> </Listeners> </ext:CheckboxSelectionModel> </SelectionModel> </ext:GridPanel>
为什么之前的方法失效?
gridPanel.setReadOnly(true):这个会把整个选择模型设为只读,所有行都无法选中或取消,不符合“仅锁定部分行”的需求。- 直接给
BeforeDeselect返回false:没有判断条件的话会阻止所有取消操作,甚至可能干扰初始加载时的内部事件流程,导致初始选中状态被覆盖。通过IsLocked属性做判断,就能精准拦截需要锁定的行。
方案二:直接禁用锁定行的复选框
如果希望视觉上明确告诉用户这些行不可修改,可以通过自定义渲染器禁用锁定行的复选框:
配置自定义CheckboxColumn
替换默认的CheckboxSelectionModel为自定义复选框列,渲染时根据IsLocked属性决定是否禁用:
<ext:GridPanel ID="gridPanel" runat="server"> <Store> <!-- 同方案一的Store配置 --> </Store> <ColumnModel runat="server"> <Columns> <!-- 自定义复选框列 --> <ext:CheckboxColumn runat="server" DataIndex="Selected" Width="50"> <Renderer Handler=" if (record.data.IsLocked) { // 锁定行渲染禁用的复选框 return '<input type=\"checkbox\" checked disabled style=\"margin:0 auto;display:block;\" />'; } else { // 非锁定行使用默认渲染逻辑 return Ext.grid.CheckboxColumn.prototype.renderer.apply(this, arguments); } " /> </ext:CheckboxColumn> <ext:Column runat="server" Text="ID" DataIndex="Id" /> <ext:Column runat="server" Text="名称" DataIndex="Name" /> </Columns> </ColumnModel> </ext:GridPanel>
这种方案下,禁用的复选框不会触发任何选择事件,用户一眼就能看出哪些行不可修改,适合对视觉提示有要求的场景。
内容的提问来源于stack exchange,提问作者S-Wing
相关产品推荐
相关产品推荐

