Доброго времени суток! Написать эту статью решил после очень пристрастного знакомства с особенностями работы WPF-контрола TreeView, особенно после очень хорошего опыта использования его младшего собрата из WinForms.
Я конечно не истина в последней инстанции, но, когда что-то не работает — ооооочень сильно бесит, когда такое же работает на другой технологии на раз. Более того — для своей работы требует очень безграничного внимания чтобы заставить это работать по-человечески. А документация не просто хромает на обе ноги — она просто переломана даже на руки по самую шею, поэтому она по гуглю и яндексу ползет передвигаясь переломанными челюстями из тех обрывков опыта, что поимели (или их уже опыт поимел) участвующих.
Передо мной стояло две основные задачи к TreeView:
1) Отобразить выбор элемента дерева
2) Позиционировать визуально на выбранный узел окно дерева, если элемент был вне зоны видимости
Как решалось:
1) Проблема выбора элемента
Те, кто работал с WinForms, привыкли, что выбор элемента — это просто приравнивание его к селекту. А тут — эээээ… только для чтения???? Да вы издеваетесь???? Ага, ООП — всегда издевается…
Просто, если быть объектом чего-то в пространстве, то нет наивысшей степени свободы от всего, нежели все собственное!
Теперь, чтобы выбор пал на элемент дерева — НАДО НЕ ДЕРЕВУ СКАЗАТЬ, что выбрать, а ЭЛЕМЕНТУ ДЕРЕВА поставить свойство IsSelected=true; То есть — берете TreeViewItem и ему даете флаг видимости. Выполнили. В WPF не дерево решает что выбрать, а компонет сам решает быть ли ему выбранным.
2) Тут вообще весело — в интернете нет ни единой внятной строки как это сделать. Помогли только знания английского и воображение. Причем воображение — сильнее всего! Почему? Да потому, если хочешь видимость узла дерева — так назначай этому узлу видимость. Я аж… ел от такого назначения очевидности. А Капитан-очевидность до сих пор нервно пьет сок в углу комнаты, глядя на эти маневры.
В общем — если надо видеть что-то в это гребаном компоненте, то надо использовать метод .BringIntoView(); Только тогда тот «контент-вьювер», сообразит, что вам надо показать так как вы этого хотели.
И еще один неприятный момент: выделить и показать — пол-дела! надо еще и отобразить! Даааааа, чтобы элемент позиционировать в окне контрола — надо его еще и развернуть по дереву! :) А вы думали! Извращения — это наше все!!! Теперь чтобы выделенный по IsSelected и развернутый по IsExpanded был видим — надо развернуть всю подноготную компонета по пути этого самого дерева. Я для себя делаю это вызовом следующего метода:
private void ExpandGroups(TreeViewItem tvi)
{
if (tvi.Parent!=null)
{
if (tvi.Parent.GetType() == typeof(TreeViewItem))
{
((TreeViewItem)tvi.Parent).IsExpanded = true;
this.ExpandGroups((TreeViewItem)tvi.Parent);
}
}
}
Он разворачивает то, что нужно, до того куда нужно… универсально.
комментарии (6)