Смена проверенного состояния узла происходит медленно в виде дерева - PullRequest
0 голосов
/ 17 октября 2018

У меня есть Map элемент управления на Form.Элемент управления картой содержит коллекцию слоев, каждый из которых имеет «IsVisible», чтобы скрыть или показать слой.

У меня есть элемент управления TreeView с CheckBoxes, где каждый 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 отстает в своем обновлении, но это не должно быть наоборот.

1 Ответ

0 голосов
/ 17 октября 2018

Я думаю, вам нужно немного переосмыслить свой дизайн.Я полагаю, карта является элементом управления TreeView?Тогда вам не нужно использовать BeginInvoke для вызова его методов.Все, что нужно, это отправить вызов в очередь и задержать операцию.Пока все в потоке пользовательского интерфейса, вам не нужно это делать.

Имейте в виду, что вызов Refresh заставит представление дерева перерисовать все дерево и ВСЕ его узлы.Это большая работа для каждого изменения узла и может не потребоваться, если вы не вызываете никаких изменений.Я также не знаком с FindFeatureLayer, поэтому не знаю, насколько эффективно он работает.

Наконец, в документации Microsoft есть примечание об установке свойства Node.Checked в событии AfterCheck.

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
}

надеюсь, это поможет, я не могу полностью проверить в настоящее время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...