Почему TreeView неожиданно рухнул в WinForms?

Что может вызвать падение TreeView, кроме вызова метода .Collapse () на TreeNode или метода .CollapseAll () TreeView?

В приложении, которое я разрабатываю, TreeView просто не будет вести себя должным образом. TreeView поддерживает только два уровня. При выборе дочернего узла родительского узла все остальные узлы немедленно сворачиваются. Однако в моем коде нет никаких вызовов методов .Collapse () или .CollapseAll ()!

Все свойства TreeView имеют значения по умолчанию, кроме свойства .LabelEdit, для которого установлено значение true. TreeView имеет некоторый код, связанный с событием AfterLabelEdit для простой процедуры проверки / MessageBox.

Я пытался:

  • Перехват события BeforeCollapse для TreeView и поднятие флага e.CancelAction.

  • Раскрытие вручную всех узлов в событии AfterView в TreeView. (Это отлично работает в качестве эксперимента, но я не намерен
    вообще запрещать коллапс узла !)

Во многих точках кода я перебираю TreeView, узел за узлом, чтобы проверить свойства. Однако никаких добавлений или удалений узлов не происходит. Единственные свойства TreeNode, которые изменяются при выборе пользователем, - это .ImageIndex и .SelectedImageIndex.

Кроме двух вышеупомянутых решений, я не имею ни малейшего представления о том, что может быть причиной этой ошибки. Даже если никакие решения не могут быть реализованы, может ли кто-нибудь иметь представление о правильном способе захвата краха? (Я попытался установить точку останова в событии BeforeCollapse, но она не сработала, если пользователь явно не свернул узел с помощью мыши или клавиатуры.)


ОБНОВИТЬ:

Проблема связана с изменением свойства .SelectedImageIndex на любом TreeNode. Изменение этого свойства приводит к разрушению всех остальных узлов.

Я попытался окружить код модификации свойства .SelectedImageIndex вызовами .BeginUpdate () и .EndUpdate (), но безрезультатно.

Как этого можно избежать?

21.07.2009 18:34:16
1 ОТВЕТ
РЕШЕНИЕ

Это побочный эффект от работы собственных окон в Windows. Многие параметры окна задаются флагами стиля в вызове CreateWindowEx (). Основные вещи, например, как выглядит граница на форме. Какой вид ViewView должен иметь. Должен ли TreeView отображать флажки.

Эти стили отображаются как свойства элемента управления. Но есть проблема. Изменение такого свойства требует воссоздания окна с нуля, чтобы в вызове CreateWindowEx () можно было указывать новые флаги стиля. Это имеет побочные эффекты, окно полностью воссоздается, поэтому оно теряет все предыдущее состояние.

Windows Forms довольно хорошо справляется с этим, восстанавливая предыдущее состояние после воссоздания окна. Но это есть утечки здесь и там. И несколько откровенных ошибок. Одна утечка в TreeView - это точное состояние, какие узлы свернуты, а какие нет. Отслеживать это просто не практично.

Для диагностики поставьте свойство Handle TreeView в окне наблюдения. Если вы видите, что это изменится, вы нашли собственность. Список флагов стиля доступен здесь, вы, вероятно, можете сопоставить их имена с соответствующим свойством.

Возможно, ясно, что для решения этой проблемы нет отличного решения, кроме как избежать изменения этого свойства. Беда, как это то, что родило WPF.

10
15.11.2017 17:26:34
Спасибо за исчерпывающий ответ! Мне удалось точно определить свойство, из-за которого дерево было воссоздано, и избежать его использования после точки инициализации. Дерево больше не забывает состояния узлов.
James 22.07.2009 13:49:05
@HansPassant, могу я узнать, почему ты откатил мои правки? Спасибо
Neuron 15.11.2017 19:14:07