powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Как сделать выделение одного узла в TreeView в Silverligth?
23 сообщений из 23, страница 1 из 1
Как сделать выделение одного узла в TreeView в Silverligth?
    #38096228
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как сделать выделение одного узла в TreeView в Silverligth, если при отображении я использую шаблон:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
 <sdk:TreeView x:Name="treeView1" Background="White" SelectedItemChanged="treeView1_SelectedItemChanged" Margin="0,1,1,1" Height="514" Width="301">
                <sdk:TreeView.ItemTemplate>
                    <sdk:HierarchicalDataTemplate ItemsSource="{Binding SubNodes}">
                    	<StackPanel>
                    		<TextBlock Text="{Binding FullHeader}" Tag="{Binding Tag}" />
                    	</StackPanel>
                    </sdk:HierarchicalDataTemplate>
                </sdk:TreeView.ItemTemplate>
 </sdk:TreeView>



А для пунктов меню я использую список экземпляров моего типа.

Код: c#
1.
2.
3.
4.
/// присвоение коллекции
List<TestServiceClient.ClassNode> itemsTrvNodes = new List<TestServiceClient.ClassNode>();
itemsTrvNodes.Add(cln);
this.treeView1.ItemsSource = itemsTrvNodes;




Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
public ClassNode()
//описание класса
	{
		//
		// TODO: добавьте логику конструктора
		//
        SubNodes = new List<ClassNode>();
        
    }   

    public int _IntTypeNode = new int();
 

    public int _IdNode = new int();

 public List<ClassNode> SubNodes { get; set; }
}



Как сделать выделение одного определенного узла дерева, причем он будет зависит от разных факторов.
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38109547
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно ли как то выделить узел в дереве?
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38111451
unknownfromrus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Solomka,

Поищи мой пост по TreeView. Я по нему очень много чего расписывал - а именно, изменение ControlTemplate. Дело в том что там будут подводные камни если оставить все как есть по умолчанию.
Я дмаю тебе не составит труда сделать небольшие изменения для добавления дополнительных тригеров для выделения.
А именно - добавь свое свойство булевского значения. Сажай в него логику выделения и добавляй его в MultiTriggers (Data). По идее ничего сложного нет
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38112140
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
unknownfromrusSolomka,

Поищи мой пост по TreeView. Я по нему очень много чего расписывал - а именно, изменение ControlTemplate. Дело в том что там будут подводные камни если оставить все как есть по умолчанию.
Я дмаю тебе не составит труда сделать небольшие изменения для добавления дополнительных тригеров для выделения.
А именно - добавь свое свойство булевского значения. Сажай в него логику выделения и добавляй его в MultiTriggers (Data). По идее ничего сложного нет

Нашла твой пост /topic/982313&hl=
Только особо не поняла, как он может мне помочь.

Нашла в интернете пример Как выделить первый узел дерева:
Код: c#
\r\n        private void SelectFistItemInCatTreeView()\r\n        {\r\n            TreeViewItem item =\r\n                treeView1.ItemContainerGenerator.ContainerFromItem(treeView1.Items[0]) as TreeViewItem;\r\n            if (item != null)\r\n            {\r\n                item.IsSelected = true;\r\n            }\r\n            \r\n        }\r\n
\r\n
Этот код работает. Достаточно вызвать этот метод и сам узел выделится.

Пыталась дальше отталкиваться...
В каком нибудь методе определяем параметр по которому нам надо выделить узел:
Код: c#
\r\nprivate void button1_Click(object sender, RoutedEventArgs e)\r\n        {\r\n              string temp = "1-171";            \r\n              SetSelectNodeTag(temp);\r\n        }\r\n
\r\n
По идее метод SetSelectNodeTag для выделение одного узла.

Код: c#
\r\n  private void SetSelectNodeTag(string varString)\r\n        {\r\n             for (int i = 0; i < treeView1.Items.Count; i++)\r\n            {\r\n                TreeViewItem item =\r\n                    treeView1.ItemContainerGenerator.ContainerFromItem(treeView1.Items[i]) as TreeViewItem;\r\n                 \r\n                SelectNodeTag03(varString, item);\r\n            }\r\n        }\r\n
\r\n

Метод SelectNodeTag по идее должен пробегать рекурсивно по всем узлам дерева, и если обнаружит искомый узел, то выделить его
Код: c#
\r\nprivate void SelectNodeTag03(string varString, TreeViewItem triCur)\r\n        {\r\n             \r\n            ClassNode nd = (ClassNode)triCur.Header; // здесь возникает ошибка при первом рекурсивном заходе\r\n            if (nd.Tag.ToString() == varString)\r\n            {\r\n                 \r\n                triCur.IsSelected = true;\r\n            }\r\n            else\r\n            {\r\n                for (int index = 0; index < triCur.Items.Count; index++)\r\n                {\r\n \r\n                    TreeViewItem searchItem = triCur.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;\r\n                     \r\n                    TreeViewItem itemTreeViewItem = triCur.ItemContainerGenerator.ContainerFromItem(searchItem) as TreeViewItem;\r\n                    TreeViewItem itemTreeViewItem2 = triCur.ItemContainerGenerator.ContainerFromItem(triCur.Items[index]) as TreeViewItem;\r\n                    TreeViewItem itemTreeViewItem3 = treeView1.ItemContainerGenerator.ContainerFromItem(triCur.Items[index]) as TreeViewItem;\r\n                   // Все три переменные null\r\n                    SelectNodeTag03(varString, itemTreeViewItem);\r\n                }\r\n            }\r\n\r\n        }\r\n
\r\n
Однако если пользоваться ранее успешно примененной логикой, не удается "достать" хотя бы один подузел.
При первом же проходе в цикле for переменные "searchItem", "itemTreeViewItem", "itemTreeViewItem2", "itemTreeViewItem3" - имею пустые значения и в следующем первом рекурсивном заходе в метод возникает ошибка в строчке:
Код: c#
\r\nClassNode nd = (ClassNode)triCur.Header\r\n
\r\n
Что нельзя обращаться к NULL.

Причем если определить первый узел дерева превого уровня, например указав string temp = "1-169"; (169 - родительский для 171), то всё нормльно работает, потому что не пытается достать подузел.
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38112716
unknownfromrus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Solomka,

Так давай по порядку.
Я правильно понимаю, что ты хочешь чтобы выделение узла в TreeView происходило не только по стандартным условиям, но ты еще свои добавишь (логику по которой должно происходить выделение)?
Мой пост тебе в помощь в том случае если ты захочешь переопределить Template у TreeView - так как возникнут подводные камни, о которых я там описывал.
В твоем же случае - чтобы добавить логику выделения - надо создать свойство, значение которого (Bool типа) будет определяться твоей логикой. И это свойство подцепить в условие IsSelected (найти его можно в Template - где определяется каким цветом и т.д. будет определяться выбранный узел). Так называемый MultiTrigger
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38113388
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
unknownfromrusSolomka,

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

Что именно подразумевается под стандартными условиями? Если под стандартными условиями подразумевается что пользователь сам выделяет необходимый узел, то ДА, мне нужно добавить свою логику, когда будет выделятся узел.

unknownfromrusВ твоем же случае - чтобы добавить логику выделения - надо создать свойство, значение которого (Bool типа) будет определяться твоей логикой. И это свойство подцепить в условие IsSelected (найти его можно в Template - где определяется каким цветом и т.д. будет определяться выбранный узел). Так называемый MultiTrigger
Я в Silverligth новичек, вот эта часть текста мне не очень понятна.

Если я правильно понимаю, то Template я так переопределяю...
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
                <sdk:TreeView.ItemTemplate >
                    
                    <sdk:HierarchicalDataTemplate ItemsSource="{Binding SubNodes}">
                    	<StackPanel>
                    		<TextBlock Text="{Binding FullHeader}" Tag="{Binding Tag}" />
                    	</StackPanel>                        
                    </sdk:HierarchicalDataTemplate>
                    
                </sdk:TreeView.ItemTemplate>



Если пишу сюда:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
            <sdk:TreeView x:Name="treeView1" Background="White" SelectedItemChanged="treeView1_SelectedItemChanged" Margin="0,1,1,1" Height="514" Width="301">
               
                <sdk:TreeView.ItemTemplate >
                    
                    <sdk:HierarchicalDataTemplate ItemsSource="{Binding SubNodes}">
                    	<StackPanel>
                    		<TextBlock Text="{Binding FullHeader}" Tag="{Binding Tag}" />
                    	</StackPanel>                        
                    </sdk:HierarchicalDataTemplate>
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                </sdk:TreeView.ItemTemplate>
            </sdk:TreeView>


То в дизайнере, выдается ошибка
Свойство "ItemTemplate" установлено больше одного раза.

Куда надо прописать свойство, чтобы можно было выделать не только узлы первого уровня, но и большего уровня вложенности?
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38114228
unknownfromrus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Solomka,

Расписывать че-то не хочется.
Давай сделаем так - дай мне свой примерчик что ты хочешь сделать - я его поправлю - добавив то что ты хочешь
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38118234
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
unknownfromrusSolomka,

Расписывать че-то не хочется.
Давай сделаем так - дай мне свой примерчик что ты хочешь сделать - я его поправлю - добавив то что ты хочешь

Ссылка на архив: http://yadi.sk/d/drPA-r0D20ITx
Не совсем родной проект, я его упростила, чтобы не отвлекать на сторонние вещи.
Слева дерево. справа список с ID узлов дерева.
И по ID надо выбрать узел в дереве.
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38121521
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор
Код: c#
1.
ClassNode nd = (ClassNode)triCur.Header

Что здесь происходит? Ты пытаешься взять Header из triCur, из типа TreeViewItem. Ты где-то до этого кладешь в Header ClassNode? Если ты этого не делаешь, то TreeViewItem'у в Header'е неоткуда взяться.

Насколько я вижу по коду, тебе нужно делать:
Код: c#
1.
ClassNode nd = (ClassNode)triCur.DataContext

а не то, что ты сейчас делаешь.

Во-вторых, лучше не доставать из TreeView TreeViewItem'ы при помощи ItemContainerGenerator'а и не работать с элементами интерфейса (TreeViewItem'ами) вручную, а, как тебе уже верно посоветовали, завести в твоем классе данных (ClassNode) свойство IsSelected, реализовать в ClassNode интерфейс INotifyPropertyChanged и установить двухсторонний (TwoWay) биндинг между TreeViewItem'ами и ClassNode с помощью ItemContainerStyle или чего-то подобного. Далее ты можешь выбрать некоторое количество ClassNode'ов, выставить им IsSelected в true и связанные с ними TreeViewItem'ы сами станут выбранными.

В-третьих, попробуй скачать проект по своей ссылке. У меня ничего не получилось.
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38122673
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
enigmatic
В-третьих, попробуй скачать проект по своей ссылке. У меня ничего не получилось.

Странно, у меня всё получается.
На всякий случай ещё сюда выложила.
http://rapidshare.com/files/1787905320/wsTestSelectNodeToInet.zip
] http://rapidshare.com/files/1787905320/wsTestSelectNodeToInet.zip
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38122684
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
enigmaticавтор
Код: c#
1.
ClassNode nd = (ClassNode)triCur.Header

Что здесь происходит? Ты пытаешься взять Header из triCur, из типа TreeViewItem. Ты где-то до этого кладешь в Header ClassNode? Если ты этого не делаешь, то TreeViewItem'у в Header'е неоткуда взяться.

Насколько я вижу по коду, тебе нужно делать:
Код: c#
1.
ClassNode nd = (ClassNode)triCur.DataContext

а не то, что ты сейчас делаешь.

Я ничего не кладу в Header, я через отладку нашла, что это поле содержит информацию о экземпляре класса ClassNode.
Код: c#
1.
ClassNode nd = (ClassNode)triCur.DataContext


Попробовала всё равно не помогает.
enigmatic
Во-вторых, лучше не доставать из TreeView TreeViewItem'ы при помощи ItemContainerGenerator'а и не работать с элементами интерфейса (TreeViewItem'ами) вручную, а, как тебе уже верно посоветовали, завести в твоем классе данных (ClassNode) свойство IsSelected, реализовать в ClassNode интерфейс INotifyPropertyChanged и установить двухсторонний (TwoWay) биндинг между TreeViewItem'ами и ClassNode с помощью ItemContainerStyle или чего-то подобного. Далее ты можешь выбрать некоторое количество ClassNode'ов, выставить им IsSelected в true и связанные с ними TreeViewItem'ы сами станут выбранными.

Не очень понимаю, может ли мне это помочь.
Мне же надо чтобы выделенные узлы дерева менялись, в процессе работы и не были одним и тем же постоянным узлом...
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38122792
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
enigmaticавтор
Код: c#
1.
ClassNode nd = (ClassNode)triCur.Header

Что здесь происходит? Ты пытаешься взять Header из triCur, из типа TreeViewItem. Ты где-то до этого кладешь в Header ClassNode? Если ты этого не делаешь, то TreeViewItem'у в Header'е неоткуда взяться.

Насколько я вижу по коду, тебе нужно делать:
Код: c#
1.
ClassNode nd = (ClassNode)triCur.DataContext

а не то, что ты сейчас делаешь.



Тут получается ошибка в строке
Код: c#
1.
ClassNode nd = (ClassNode)triCur.Header


возникает из-за того что мы в метод передаем переменную itemTreeViewItem2 NULL.
Код: c#
1.
 SelectNodeTag03(varString, itemTreeViewItem2);
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38122948
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolomkaЯ ничего не кладу в Header, я через отладку нашла, что это поле содержит информацию о экземпляре класса ClassNode.
Странно, по идее в Header'e не должно быть ClassNode, но ClassNode должен быть в DataContext'е triCur.

Solomkaenigmatic
Во-вторых, лучше не доставать из TreeView TreeViewItem'ы при помощи ItemContainerGenerator'а и не работать с элементами интерфейса (TreeViewItem'ами) вручную, а, как тебе уже верно посоветовали, завести в твоем классе данных (ClassNode) свойство IsSelected, реализовать в ClassNode интерфейс INotifyPropertyChanged и установить двухсторонний (TwoWay) биндинг между TreeViewItem'ами и ClassNode с помощью ItemContainerStyle или чего-то подобного. Далее ты можешь выбрать некоторое количество ClassNode'ов, выставить им IsSelected в true и связанные с ними TreeViewItem'ы сами станут выбранными.
Не очень понимаю, может ли мне это помочь.
Мне же надо чтобы выделенные узлы дерева менялись, в процессе работы и не были одним и тем же постоянным узлом...Эм, функционал редактирования узлов нужен?

Solomka http://rapidshare.com/files/1787905320/wsTestSelectNodeToInet.zip rapidshareСкачивание невозможно
Download permission denied by uploader. (0b67c2f5)
SolomkaСсылка на архив: http://yadi.sk/d/drPA-r0D20ITx Тут выдается первая страница, где есть кнопка "просмотреть", по которой куча файлов, которые нельзя скачать.

авторТут получается ошибка в строке
ClassNode nd = (ClassNode)triCur.Header

возникает из-за того что мы в метод передаем переменную itemTreeViewItem2 NULL.
SelectNodeTag03(varString, itemTreeViewItem2);Хорошо, если у тебя там в Header'e всё-таки лежит ClassNode, то лучше выложи свой проект где-нибудь откуда скачать можно.
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38123348
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
enigmaticвозникает из-за того что мы в метод передаем переменную itemTreeViewItem2 NULL.
SelectNodeTag03(varString, itemTreeViewItem2);Хорошо, если у тебя там в Header'e всё-таки лежит ClassNode, то лучше выложи свой проект где-нибудь откуда скачать можно.

https://docs.google.com/file/d/0BxprtRW4TI9QWjRkWXBEcGxYOHM/edit

http://depositfiles.com/files/0dvgppejn

http://disk.yandex.ru/public/?hash=85sSp5Ko4N1JPPvUVo6pTeb4nWqfxhhYcWV4li0RjOo%3D
(тут есть кнопочка посмотреть и скачать и сохранить на яндекс.диск)
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38128462
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Solomka,

Окей, TreeViewItem зачем-то хранит информацию о привязанных данных не в DataContext (где должен, по идее), а в Header (которого у него нет, по сути). Это во-первых.

Во-вторых, сложно сказать почему именно не работает то, что ты хочешь. Просто код кошмарен и его проще переписать заново.
В теме уже указывалось как это лучше сделать.
unknownfromrusВ твоем же случае - чтобы добавить логику выделения - надо создать свойство, значение которого (Bool типа) будет определяться твоей логикой. И это свойство подцепить в условие IsSelected (найти его можно в Template - где определяется каким цветом и т.д. будет определяться выбранный узел).
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38135684
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
enigmaticSolomka,

Окей, TreeViewItem зачем-то хранит информацию о привязанных данных не в DataContext (где должен, по идее), а в Header (которого у него нет, по сути). Это во-первых.

При замене на DataContext все арвно происходит ошибка.
enigmaticВо-вторых, сложно сказать почему именно не работает то, что ты хочешь. Просто код кошмарен и его проще переписать заново.
В теме уже указывалось как это лучше сделать.

Если бы , было мне бы понятно, то я бы уже не спрашивала.
Можно скинуть пример, чтобы попонятнее было?

Кошмарен - не кошмарен... мой код... сказать сложно.
В интернете нашла пример с таким кодом
И он почти рабочий, для узлом первого уровня
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38139830
Solomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
unknownfromrusВ твоем же случае - чтобы добавить логику выделения - надо создать свойство, значение которого (Bool типа) будет определяться твоей логикой. И это свойство подцепить в условие IsSelected (найти его можно в Template - где определяется каким цветом и т.д. будет определяться выбранный узел). Так называемый MultiTrigger
Можете скинуть пример кода?
А то не совсем понятно...
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38141297
unknownfromrus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Solomka,

Давай скидывай
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38145079
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сам недавно столкнулся с такой проблемой. Вроде бы выделить узел по его датаконтексту - не особенно трудный вопрос:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register(
      "SelectedObject", typeof(object), typeof(WxTreeView),
      new PropertyMetadata(SelectedObjectChangedCallback));

[Bindable(true)]
public object SelectedObject
{
  get { return GetValue(SelectedObjectProperty); }
  set { SetValue(SelectedObjectProperty, value); }
}

private static void SelectedObjectChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs eventArgs)
{
  var treeView = (WxTreeView)obj;
  if (ReferenceEquals(eventArgs.OldValue, eventArgs.NewValue)) return;
  var item = GetSelectedItem(treeView, eventArgs.NewValue) as TreeViewItem;
  if (item == null) return;
  item.Focus();
}
private static ItemsControl GetSelectedItem(ItemsControl parent, object itemToSelect)
{
  if (parent == null) return null;
  var childTreeNode = parent.ItemContainerGenerator.ContainerFromItem(itemToSelect) as TreeViewItem;
  if (childTreeNode!=null)
    return childTreeNode;
  foreach (var childItem in parent.Items)
  {
    var childItemsControl = parent.ItemContainerGenerator.ContainerFromItem(childItem) as ItemsControl;
    var res = GetSelectedItem(childItemsControl, itemToSelect);
    if (res!=null) return res;
  }
  return null;
}


однако вся проблема - в виртуализации отрисовки: свернутые узлы не отображают своего содержимого, фактически - не содержат его, и на уровне вложенности глубже 2 от корня, если развернут только корень, ItemContainerGenerator.ContainerFromItem(itemToSelect) возвращает null. Т.е. по мере прохода по дереву вглубь надо разворачивать узлы. Но просто установки IsExpanded = true недостаточно - при этом только устанавливается значение DependencyProperty, а заполнение ItemsControl узлами порисходит в отложенном порядке. У TreeView есть метод ExpandSubtree(), но он разварачивает всё поддерево, а надо развернуть только 1 уровень. Пришлось взять рефлектор, влезть в код TreeViewItem, взять оттуда реализацию ExpandSubtree, и модифицировать её (часть используемых методов/свойств там protected internal, поэтому пришлось прибегнуть к reflection). Получилось вот так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
public static void TraverseDown(this ItemsControl root, IEnumerable<object> traverse)
{
  if (traverse == null || !traverse.Any())
    return;
  var ic = root;
  foreach(var o in traverse)
  {
    var tvi = ic.ItemContainerGenerator.ContainerFromItem(o) as TreeViewItem;
    if (tvi == null) break;
    tvi.UpdateLayout();
    if (!tvi.IsExpanded) ExpandLevel(tvi);
    ic = tvi;
  }
}

public static Panel ItemsHost(this TreeViewItem item)
{
  var ihp = typeof(TreeViewItem).GetProperty("ItemsHost", BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance);
  return ihp.GetValue(item, null) as Panel;
}

private static void ExpandLevel(TreeViewItem item)
{
  if (item == null) return;
  if (item.GetIsBound(TreeViewItem.IsExpandedProperty))
    item.SetBindingValue(TreeViewItem.IsExpandedProperty, true);
  else
    item.SetValue(TreeViewItem.IsExpandedProperty, true);
  item.ApplyTemplate();
  var itemsPresenter = (ItemsPresenter)item.Template.FindName("ItemsHost", item);
  if (itemsPresenter != null)
    itemsPresenter.ApplyTemplate();
  else
    item.UpdateLayout();
  var virtualizingPanel = item.ItemsHost() as VirtualizingPanel;
  var egInfo = typeof(Panel).GetMethod("EnsureGenerator", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance);
  egInfo.Invoke(item.ItemsHost(), null); //item.ItemsHost().EnsureGenerator();
  var biivInfo = typeof(VirtualizingPanel).GetMethod("BringIndexIntoView", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance);
  var i = 0;
  var count = item.Items.Count;
  while (i < count)
  {
    if (virtualizingPanel != null)
    {
      biivInfo.Invoke(virtualizingPanel, new object[] { i }); //virtualizingPanel.BringIndexIntoView(i);
    }
    else
    {
      var treeViewItem = (TreeViewItem)item.ItemContainerGenerator.ContainerFromIndex(i);
      treeViewItem.BringIntoView();
    }
    i++;
  }
}


В комментариях - то, что было в исходном коде. Методы GetIsBound/SetBindingValue используются для того, чтобы в случае, если свойство IsExpanded имеет привязку к модели, изменять (опять же через reflection) свойство модели, а не значение IsExpandedProperty непосредственно, т.к. это сбросит биндинг свойства.
Ну, и в результате получаем
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
private static void SelectedObjectChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs eventArgs)
{
  var treeView = (WxTreeView)obj;
  if (ReferenceEquals(eventArgs.OldValue, eventArgs.NewValue)) return;
  var item = GetSelectedItem(treeView, eventArgs.NewValue) as TreeViewItem;
  if (item == null)
  {
    var traversable = eventArgs.NewValue as ITraversable;
    if (traversable == null) return;
    treeView.TraverseDown(traversable.Traverse);
    item = GetSelectedItem(treeView, eventArgs.NewValue) as TreeViewItem;
  }
  if (item == null) return;
  item.Focus();
}


Интрефейс ITraversable заставляет объект модели дерева возвращать все родительские узлы дерева от корня до требуемого элемента. Выглядит он так:
Код: c#
1.
2.
3.
4.
public interface ITraversable
{
  IEnumerable<object> Traverse { get; }
}


и реализуется рекурсией.
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38145480
enigmatic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны,

Хм, а зачем решать проблему на уровне контролов (TreeViewItem'ов), если можно объявить свойство IsSelected (+INPC) в модели и забиндиться на него?
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38145560
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
enigmaticХм, а зачем решать проблему на уровне контролов (TreeViewItem'ов), если можно объявить свойство IsSelected (+INPC) в модели и забиндиться на него?
Затем, что я писал выше:
Сон Веры ПавловныНо просто установки IsExpanded = true недостаточно - при этом только устанавливается значение DependencyProperty, а заполнение ItemsControl узлами происходит в отложенном порядке.
Аналогично без толку выставлять в true свойство модели, забинденное на IsExpanded - ItemContainerGenerator.ContainerFromItem(itemToSelect) будет возвращать null, т.к. ItemsControl узла на момент после установки свойства не заполнится соответствующими контролами. Это всё проверено на практике.
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38145870
unknownfromrus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны,

Не знаю почему бестолку.
Недавно сделал тривью в комбобоксе. У меня были вложенные объекты. К объектам добавил свойство IsExpanded (поле класса объекта). Установил биндинг - и у меня разворачивается независимо от вложенности объектов (ЗАполнение объектов реализовано через HierarchiDataTemplate). Аналогично с IsSelected.
Вытаскивать из проекта Тривью я не хочу, чтобы тут выкладывать.
Тот кто поднимал тему - ему по ходу по фиг - раз до сих пор не выложил примерчик кода - я хотел попробовать в нем переопределить тривью
...
Рейтинг: 0 / 0
Как сделать выделение одного узла в TreeView в Silverligth?
    #38190719
Obrazer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
unknownfromrusУстановил биндинг - и у меня разворачивается независимо от вложенности объектов (ЗАполнение объектов реализовано через HierarchiDataTemplate). Аналогично с IsSelected.

А где биндинг делается и какого контрола? В HierarchiDataTemplate что-то или в самом TreeView?
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Как сделать выделение одного узла в TreeView в Silverligth?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]