You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:35:55