На самом деле, это проектно.
В конце документации для свойства 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;
}