【问题标题】:Changing of node's checked state is slow in treeview在树视图中更改节点的检查状态很慢
【发布时间】:2019-03-22 02:32:40
【问题描述】:

我在Form 上有一个Map 控件。地图控件包含一组图层,每个图层都有一个“IsVisible”来隐藏或显示图层。

我有一个带有CheckBoxesTreeView 控件,每个node 代表一个层,全部包含在一个父级node 下。

当我选中/取消选中节点时,我希望相关层的IsVisible 属性设置为等于节点的选中状态。

这是我目前正在做的事情:

private void LayerTreeView_AfterCheck(object sender, TreeViewEventArgs e)
{
    if (e.Node.Parent == null) //if it's a parent node, make any children nodes match its checked state
    {
        foreach (TreeNode node in e.Node.Nodes)
        {
            node.Checked = e.Node.Checked;
            Map.BeginInvoke((MethodInvoker)delegate () { Map.FindFeatureLayer(node.Name).IsVisible = node.Checked; });
        }
    }
    else //it's a child node
    {
        Map.FindFeatureLayer(e.Node.Name).IsVisible = e.Node.Checked;
    }
    Map.BeginInvoke((MethodInvoker)delegate () { Map.Refresh(); }); //culprit is here
}

问题在于,随着我拥有的层/节点越多,明显的延迟就会增加。在上面的代码中,最后一行包含Map.Refresh();

在调用 Map.Refresh() 之前,节点不会明显更新,对于每个已更改其检查状态的节点都会调用该函数。这会导致延迟。我需要节点立即更新。 Map 控件是否在刷新时滞后并不重要,但不应该相反。

【问题讨论】:

    标签: c# winforms checkbox treeview


    【解决方案1】:

    我认为您需要重新考虑一下您的设计。我假设 Map 是 TreeView 控件?那么您不需要使用 BeginInvoke 来调用它的方法。所做的只是将呼叫推入队列并延迟操作。只要一切都在 UI 线程上,您就不需要这样做。

    请记住,调用 Refresh 将导致树视图重绘整个树及其所有节点。对于每个节点更改来说,这需要大量工作,如果您不调用任何更改,则可能没有必要。我也不熟悉 FindFeatureLayer,所以不知道它的工作效率如何。

    最后,Microsoft 文档中有一条关于在 AfterCheck 事件中设置 Node.Checked 属性的说明。

    Setting the TreeNode.Checked property from within the BeforeCheck or AfterCheck event
    causes the event to be raised multiple times and can result in unexpected behavior. For
    example, you might set the Checked property in the event handler when you are
    recursively updating the child nodes so that the user does not have to expand and check
    each one individually. To prevent the event from being raised multiple times, add logic
    to your event handler that only executes your recursive code if the Action property of
    the TreeViewEventArgs is not set to TreeViewAction.Unknown. For an example of how to do
    this, see the Example section of the AfterCheck or BeforeCheck events.
    

    所以也许这样会更好???

    if(e.Action != TreeViewAction.Unknown)
    {
        if (e.Node.Parent == null) //if it's a parent node, make any children nodes match its checked state
        {
            foreach (TreeNode node in e.Node.Nodes)
            {
                node.Checked = e.Node.Checked;
                Map.FindFeatureLayer(node.Name).IsVisible = node.Checked;
            }
        }
        else //it's a child node
        {
            Map.FindFeatureLayer(e.Node.Name).IsVisible = e.Node.Checked;
        }
        //Map.Refresh();   // You may not need this if everything is immediate
    }
    

    希望这会有所帮助,我目前无法完全测试。

    【讨论】:

    • 地图是一个单独的控件。树视图只是地图控件具有的图层的表示,但它是独立的。感谢MS提供的说明,我没有看到!
    猜你喜欢
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多