简体   繁体   English

在树状视图中更改节点的检查状态很慢

[英]Changing of node's checked state is slow in treeview

I have a Map control on a Form . 我在Form上有一个Map控件。 The map control contains a collection of layers which each have a "IsVisible" to hide or show the layer. 地图控件包含一个图层集合,每个图层都有一个“ IsVisible”以隐藏或显示该图层。

I have a TreeView control with CheckBoxes with each node representing a layer, all contained under a single parent node . 我有一个带有CheckBoxesTreeView CheckBoxes ,每个node代表一个层,所有node都包含在一个父node

When I check/uncheck a node, I want the related layer's IsVisible property to be set equal to the node's checked state. 当我检查/取消选中节点时,我希望将相关层的IsVisible属性设置为等于节点的选中状态。

Here's what I'm currently doing: 这是我目前正在做的事情:

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
}

The problem is that there is a noticeable lag which increases with the more layers/nodes I have. 问题在于,随着我拥有的层数/节点数的增加,会有明显的延迟。 In the code above, the last line contains the Map.Refresh(); 在上面的代码中,最后一行包含Map.Refresh();

The nodes don't update visibly until the Map.Refresh() is called, which is called for each node that has it's checked state changed. 在调用Map.Refresh()之前,这些节点不会进行可见更新,对于已更改其检查状态的每个节点都将调用该方法。 This causes the delay. 这导致延迟。 I need the nodes to update immediately. 我需要立即更新节点。 It doesn't matter if the Map control lags behind with it's refresh, but it shouldn't be the opposite. Map控件的更新是否滞后并不重要,但不应该相反。

I think you need to rethink your design a bit. 我认为您需要重新考虑一下您的设计。 I assume Map is the TreeView control? 我假设Map是TreeView控件? Then you shouldn't need to use BeginInvoke to call its methods. 然后,您不需要使用BeginInvoke来调用其方法。 All that does is push the call into the queue and delay the operation. 所有要做的就是将呼叫推入队列并延迟操作。 As long as everything is on the UI thread, you shouldn't need to do that. 只要所有内容都在UI线程上,您就不需要这样做。

Keep in mind calling Refresh is going to cause the treeview to redraw the entire tree and ALL its nodes. 请记住,调用Refresh将导致树视图重绘整个树及其所有节点。 That is a lot of work for every node change and may not be necessary if you don't invoke any changes. 对于每个节点更改,这都是很多工作,如果您不调用任何更改,则可能没有必要。 I also am not familiar with FindFeatureLayer so don't know how efficiently it works. 我也不熟悉FindFeatureLayer,所以不知道它的工作效率如何。

Finally, Microsoft documentation has a note about setting the Node.Checked property in the AfterCheck event. 最后,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.

so maybe this would be better??? 所以也许这会更好???

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
}

hopefully that helps, I'm not able to fully test currently. 希望有帮助,我目前无法完全测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM