Where is the IsSynchronizedWithCurrentItem property (or equivalent) for TreeView?

Say it is not .

I have a regular windows / file explorer such as setup.

  • Left side I have a TreeView with all the data connected by nodes in the hierarchy
  • Right side I have a ListView showing Node.Properties

ListView has the IsSynchronizedWithCurrentItem property, which clears. for example, If I had another ListView showing a list of nodes, and both listViews have this property set to true. Changing node selection in NodesListView will automatically update PropertiesListView.

Now I need the same thing with NodesTreeView and PropertiesListView ... and it looks like TreeView does not have such a property.

Is there a more β€œWPF way” to solve this problem? Or I need to handle the NodeSelectionChanged event of the tree and update the listView with code.

+6
data-binding wpf
source share
4 answers

A really simple solution is to bind the "details" user interface elements to the SelectedValue TreeView property. For example, if your TreeView looked like this:

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

Then you can bind the user interface details (for example, a text field) using:

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

Causes the text field to bind to the Name property of the elements currently selected in the TreeView.

If you want to associate many user interface elements with data for the selected TreeView element, consider setting up a DataContext on an element that contains all the part controls (DockPanel / Grid / StackPanel, etc.).

+6
source share

Why this property does not implement this, I do not know, but I have a suggestion below.

Your code above will work, however this is not what the IsSynchronizedWithCurrentItem property does. Any ItemsControl is associated with an ICollectionView of the ItemsSource property. To get this ICollectionView, we can call CollectionViewSource.GetDefaultCollectionView (object o). Depending on the type of object o, you get another specific implementation of ICollectionView inteface. CollectionView and ListCollectionView are two specific classes that come to mind.

The ICollectionView interface contains a member called CurrentItem. What IsSynchronizedWithCurrentItem does: whenever an item is clicked on an ItemsControl, it sets CurrentItem to view the collection. ICollectionView also has two events: CurrentItemChanging and CurrentItemChanged. When the IsSynchronizedWithCurrentItem property is set, ItemControl will update SelectedItem based on what ICollectionView CurrentItem is. Has the meaning?

In master / detail WPF scripting scripts, we simply bind to ICollectionViews and their CurrentItem (the syntax of CurrentItem is something like {Binding Items / Name}, where Name is the Name property in the CurrentItem collection.

So, although your code works for your purposes, it does not do what this property does. To do what the property does, you need to do the following:

  • When an item is selected, you need to find out which collection it belongs to. How do we do this? I believe that is why TreeView does not implement it. The selected item is displayed in the TreeViewItem. DataContext is the object itself, but what is a parent collection? I think in order to get it, you can either cache it in some hashmap (stupid, but work), or you can go to the logical tree and get the parent TreeViewItem, which turns out to be the ItemsControl. The ItemsSource property will be your collection.
  • Get the ICollectionView for this collection.
  • You need to use this ICollectionView in the CollectionView (ICollectionView does not implement the CurrentItem customization tool)
  • Call SetCurrent (.., ..) on an instance of CollectionView

Now everything related to this ICollectionView CurrentItem will be updated.

It has become more than I expected. Let me know if any clarification is needed.

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

Where " .Modules " is the set of children from the selected tree element that you want to display. Do not worry about attaching the " SelectedItemChanged " event in the tree.

+3
source share

My solution for this turned out to be pretty tiny .. I don’t know if it is equivalent to IsSynchronizedWithCurrentItem. ListView is updated as expected.

 // 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 } 
0
source share

All Articles