Где находится свойство IsSynchronizedWithCurrentItem (или его эквивалент) для TreeView? - PullRequest
6 голосов
/ 17 декабря 2008

Скажи мне, что это не так .

У меня есть типичный Windows / File Explorer, как установка.

  • Левая сторона У меня есть TreeView, все данные привязаны, показывая узлы в иерархии
  • Правая сторона У меня есть ListView, показывающий Node.Properties

ListView имеет свойство IsSynchronizedWithCurrentItem, которое имеет значение. например Если бы у меня был другой ListView, показывающий список узлов, и оба listViews имели бы для этого свойства значение true. Изменение выбора узла в NodesListView автоматически обновит PropertiesListView.

Теперь мне нужно то же самое с NodesTreeView и PropertiesListView ... и кажется, что TreeView не имеет такого свойства.

Есть ли более «способ WPF» для решения этой проблемы? Или мне нужно обработать событие NodeSelectionChanged дерева и обновить listView с помощью кода.

Ответы [ 4 ]

6 голосов
/ 09 февраля 2009

Действительно простое решение - привязать элементы пользовательского интерфейса «детализация» к свойству SelectedValue TreeView. Например, если ваш TreeView выглядел так:

<TreeView Name="CategoryName" ItemsSource="{Binding Source={StaticResource A_Collection}, Path=RootItems}" />

Затем вы можете связать элементы пользовательского интерфейса деталей (например, текстовое поле), используя:

<TextBox Text="{Binding ElementName=CategoryTreeView, Path=SelectedValue.Name}"/>

Будет ли текстовое поле привязано к свойству Name элементов, выбранных в данный момент в TreeView.

Если вы хотите связать многие элементы пользовательского интерфейса в качестве подробностей для выбранного элемента TreeView, рассмотрите возможность установки DataContext для элемента, который содержит все элементы управления сведениями (DockPanel / Grid / StackPanel и т. Д.).

4 голосов
/ 06 марта 2009
<ListView Name="listView1" 
    ItemsSource="{Binding Path=SelectedItem.Modules, 
                          ElementName=treeView1, Mode=OneWay}" 
    IsSynchronizedWithCurrentItem="True">

Где ".Modules" - это коллекция дочерних элементов от выбранного элемента дерева, который вы хотите отобразить. Не беспокойтесь о подключении события "SelectedItemChanged" в древовидной структуре.

3 голосов
/ 17 декабря 2008

Почему именно он не реализует свойство, я не знаю, но у меня есть предложение внизу.

Ваш код выше будет работать, однако это не то, что делает свойство IsSynchronizedWithCurrentItem. Любой ItemsControl привязывается к ICollectionView свойства ItemsSource. Чтобы получить этот ICollectionView, мы можем вызвать CollectionViewSource.GetDefaultCollectionView (объект o). В зависимости от типа объекта o, вы получаете различную конкретную реализацию интерфейса ICollectionView. CollectionView и ListCollectionView - это два конкретных класса, которые приходят на ум.

Интерфейс ICollectionView содержит член с именем CurrentItem. Что делает IsSynchronizedWithCurrentItem: при каждом нажатии элемента на ItemsControl он устанавливает CurrentItem для представления коллекции. ICollectionView также имеет два события: CurrentItemChanging и CurrentItemChanged. Когда свойство IsSynchronizedWithCurrentItem установлено, ItemsControl обновит SelectedItem на основе того, что представляет собой CurrentItem объекта ICollectionView. Имеет смысл?

В сценариях master / detail WPF мы просто привязываемся к ICollectionViews и их CurrentItem (синтаксис CurrentItem - это что-то вроде {Binding Items / Name}, где Name - это свойство Name в CurrentItem коллекции.

Так что, хотя ваш код работает для ваших целей, он не делает то, что делает это свойство. Чтобы сделать то, что делает свойство, вам нужно сделать следующее:

  1. Когда элемент выбран, вам нужно выяснить, к какой коллекции он принадлежит. как нам это сделать? Я считаю, что именно поэтому TreeView не реализует это. Выбранный элемент отображается в TreeViewItem. DataContext - это сам объект, но что такое родительская коллекция? Я думаю, чтобы получить его, вы можете либо кэшировать его в некотором хэш-файле (глупо, но будет работать), либо вы можете пройти по логическому дереву и получить родительский элемент TreeViewItem, который оказывается ItemControl. Свойство ItemsSource будет вашей коллекцией.
  2. Получите ICollectionView для этой коллекции.
  3. Необходимо преобразовать этот ICollectionView в CollectionView (ICollectionView не реализует установщик CurrentItem)
  4. Вызовите SetCurrent (.., ..) для экземпляра CollectionView

Теперь все, что связано с текущим элементом ICollectionView, будет обновлено.

Это стало длиннее, чем я ожидал. Дайте мне знать, если необходимы дальнейшие разъяснения.

0 голосов
/ 17 декабря 2008

Мое решение оказалось довольно крошечным ... не знаю, эквивалентно ли это IsSynchronizedWithCurrentItem. ListView обновляется, как и ожидалось.

// the XAML
<TreeView DockPanel.Dock="Left" x:Name="tvwNodes" ItemsSource="{Binding}" SelectedItemChanged="OnNewNodeSelected"/>
<ListView x:Name="lvwProperties" ItemsSource="{Binding Path=Properties}"

// the code-behind
private void OnNewNodeSelected(object sender, RoutedPropertyChangedEventArgs<object> e)
{
  lvwProperties.DataContext = tvwNodes.SelectedItem; // this returns the selected Node obj
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...