Где находится свойство IsSynchronizedWithCurrentItem (или его эквивалент) для TreeView?


person Gishu    schedule 17.12.2008    source источник


Ответы (4)


Действительно простое решение состоит в том, чтобы привязать ваши элементы пользовательского интерфейса «детали» к свойству 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 и т. д.).

person Mark    schedule 09.02.2009

<ListView Name="listView1" 
    ItemsSource="{Binding Path=SelectedItem.Modules, 
                          ElementName=treeView1, Mode=OneWay}" 
    IsSynchronizedWithCurrentItem="True">

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

person Community    schedule 06.03.2009
comment
Это определенно решение, работает с шармом! К вашему сведению: это невозможно связать с помощью графического интерфейса Blend. - person Daniel Eisenreich; 14.08.2018

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

Ваш код выше будет работать, однако это не то, что делает свойство IsSynchronizedWithCurrentItem. Любой ItemsControl привязывается к ICollectionView свойства ItemsSource. Чтобы получить этот ICollectionView, мы можем вызвать CollectionViewSource.GetDefaultCollectionView(object 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, который оказывается ItemsControl. Свойство ItemsSource будет вашей коллекцией.
  2. Получите ICollectionView для этой коллекции.
  3. Необходимо преобразовать этот ICollectionView в CollectionView (ICollectionView не реализует установщик CurrentItem)
  4. Вызов SetCurrent(.., ..) в экземпляре CollectionView

Теперь все, что связано с CurrentItem этого ICollectionView, будет обновлено.

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

person Szymon Rozga    schedule 17.12.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
}
person Gishu    schedule 17.12.2008