Странное поведение автоматического свертывания в древовидной структуре, когда установлен SelectedImageIndex? - PullRequest
0 голосов
/ 28 марта 2020

В древовидной структуре управления желаемое поведение клавиатуры по умолчанию - использование клавиш со стрелками влево / вправо для свертывания / развертывания и клавиш со стрелками вверх / вниз для перемещения по видимым узлам без свертывание или развертывание их.

Но по какой-то странной причине следующий код автоматически сворачивает / разворачивает узлы при использовании клавиш со стрелками вверх / вниз для их выбора:

private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
    // This line produces strange auto-collapse/expand behaviour,
    // but is needed in order to correctly set the image of the selected node.
    // If I comment this line out, then keyboard input produces the desired behaviour.
    treeView1.SelectedImageIndex = e.Node.ImageIndex;
}
  1. Почему это происходит?
  2. Как это можно предотвратить?

1 Ответ

2 голосов
/ 29 марта 2020

На самом деле, это проектно.

В конце документации для свойства TreeView.SelectedImageIndex:

При установке свойства SelectedImageIndex во время выполнения дескриптор TreeView воссоздается (см. Control.RecreateHandle) для обновления внешнего вида элемента управления. Это приводит к свертыванию всех узлов дерева, кроме выбранного TreeNode.

Я воспроизвел проблему и понял, что это происходит только при изменении вида дерева SelectedImageIndex (Не при назначении, а при присваивается другое значение). Если вы выбираете узел с ImageIndex 8, а затем выбираете другой узел с таким же индексом изображения, это нежелательное поведение не возникает.

Но; В любом случае, есть решение. Он не идеален, но может быть улучшен.

Решение состоит в том, чтобы сохранить развернутые узлы в пользовательской коллекции и развернуть их после назначения .SelectedImageIndex, и только в случае изменения SelectedImageIndex.

В приведенном ниже коде есть много обходных путей. Я объясню в строках комментариев, когда у меня будет время, но, может быть, вы можете попробовать его тем временем.

    private List<TreeNode> expandedNodes = new List<TreeNode>();
    private TreeNode nodeAboutToCollapse;

    private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
    {
        // skip system calls
        if(e.Action == TreeViewAction.Unknown)
        {
            return;
        }

        if (treeView1.SelectedImageIndex == e.Node.ImageIndex)
        {
            nodeAboutToCollapse = null;
            return;
        }

        treeView1.SelectedImageIndex = e.Node.ImageIndex;

        for (int i = 0; i < expandedNodes.Count; i++)
        {
            if (expandedNodes[i] != nodeAboutToCollapse)
            {
                expandedNodes[i].Expand();
            }
        }
        nodeAboutToCollapse = null;
    }

    private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
    {
        if (!expandedNodes.Contains(e.Node))
        {
            expandedNodes.Add(e.Node);
        }
    }

    private void treeView1_AfterCollapse(object sender, TreeViewEventArgs e)
    {
        expandedNodes.Remove(e.Node);
        nodeAboutToCollapse = null;
    }

    private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
    {
        nodeAboutToCollapse = e.Node;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...