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

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

У меня есть типичный проводник Windows / файлов, например setup.

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
10 405
4

Ответы 4

Мое решение оказалось довольно крошечным ... не знаю, эквивалентно ли оно 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
}

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

Ваш код выше будет работать, однако это не то, что делает свойство 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. Имеет смысл?

В основных / подробных сценариях 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, будет обновлено.

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

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

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

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

Определенно решение, работает с шармом! К вашему сведению: привязать это через графический интерфейс Blend невозможно.

Daniel Eisenreich 14.08.2018 12:12

Другие вопросы по теме