You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过代码编程勾选ObjectListView的子项?

解决ObjectListView树形结构中子项无法勾选的问题

我之前也踩过这个坑!ObjectListView的CheckObject()CheckObjects()确实只对根节点生效,因为它们是基于顶层Roots集合操作的;而CheckSubItem()完全是另一个功能——它用来控制列表行中某一列的勾选状态(比如多列带CheckBox的场景),和树形子节点根本不沾边。

下面给你两种靠谱的解决方案,优先推荐第一种:


方案1:通过数据源绑定实现(最稳定)

ObjectListView本质是数据驱动的,最佳实践是让你的数据类自带勾选状态属性,和UI做双向绑定,这样不管是根节点还是子节点,修改数据源就能同步UI。

步骤1:给ExampleClass添加可绑定的勾选属性

public class ExampleClass
{
    // 你的其他业务属性...
    public bool IsChecked { get; set; } // 新增勾选状态属性
}

步骤2:配置TreeListView的CheckBox列

在设计器或者代码里,把TreeListView的CheckBox列的AspectName设置为"IsChecked",这样UI会和这个属性自动绑定。

步骤3:修改ReloadChecks方法,操作数据源

public void ReloadChecks(List<ExampleClass> toCheck)
{
    // 递归获取所有节点(根+子节点)
    var allNodes = GetAllTreeNodes(tvTreeView.Roots);
    
    // 重置所有节点的勾选状态,匹配目标列表的项就勾选
    foreach (var node in allNodes)
    {
        node.IsChecked = toCheck.Contains(node);
    }
    
    // 刷新ObjectListView,让UI同步数据源变化
    tvTreeView.RefreshObjects(allNodes);
}

// 递归遍历所有子节点的辅助方法
private IEnumerable<ExampleClass> GetAllTreeNodes(IEnumerable<object> rootNodes)
{
    foreach (var root in rootNodes.Cast<ExampleClass>())
    {
        yield return root;
        // 获取当前节点的子节点,用TreeListView内置的GetChildren方法
        var childNodes = tvTreeView.GetChildren(root).Cast<ExampleClass>();
        foreach (var child in GetAllTreeNodes(childNodes))
        {
            yield return child;
        }
    }
}

方案2:直接操作UI节点(适合临时场景)

如果不想改数据源,也可以直接操作UI节点,但要注意必须确保子节点已经被加载(比如先展开所有节点),否则Items集合里不会包含子节点。

public void ReloadChecks(List<ExampleClass> toCheck)
{
    // 先展开所有节点,确保子节点被加载到UI
    tvTreeView.ExpandAll();
    
    // 遍历所有UI节点(包括子项)
    foreach (OLVListItem listItem in tvTreeView.Items)
    {
        var dataItem = listItem.RowObject as ExampleClass;
        if (dataItem != null && toCheck.Contains(dataItem))
        {
            listItem.Checked = true;
        }
    }
}

⚠️ 注意:这种方法如果节点数量多,ExpandAll()会影响性能,而且如果TreeListView启用了虚拟化,可能还是会有部分子节点没加载到Items里,所以优先用方案1。

内容的提问来源于stack exchange,提问作者dominikz

火山引擎 最新活动