ganeshran
ganeshran

Reputation: 3512

How do I pass a Treeview's SelectedItem to another command?

I created a treeview in WPF MVVM with a hierarchical DAtaTemplate property.

Outside of the Treeview, I have an "EDIT" button. On press of edit button I want to pass the Treeview's selectedItem to the RelayCommand in the viewmodel.

I am implementing the same functionality within the TreeviewItem on double click of the node. However I want to know what is the best way to accomplish this outside.

My code structure is as follows

MainView -> MainViewModel

StateViewItem -> StateViewModel (HierarchicalDataTemplate inheriting from TreeViewItemViewModel)

RegionViewItem -> RegionViewModel (DataTemplate inheriting from TreeViewItemViewModel)

The RegionViewModel handles the double click for the node and accomplishes the Edit functionality.

However the "EDIT" button is outside of the treeview, how do I pass the selected RegionViewItem to the Command bound so I can load it for editing?

thanks in advance for help

Upvotes: 0

Views: 788

Answers (2)

Vinit Sankhe
Vinit Sankhe

Reputation: 19885

Code below is ONLY for guidance purposes for MVVM. It may / may not compile.

Way 1:

Assuming that your TreeViewItemViewModel is the base item level view model data context for all tree view items in your tree, add a writeable property in TreeViewItemViewModel called IsSelected. Dont forget to notify property changes in IsSelected's Setter.

In your XAML Tree View add the following in the Style targetted for the TreeViewItem ....

  <TreeView.Resources>
      <Style TargetType="{x:Type TreeViewItem}">
          <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
      </Style> 
  </TreeView.Resources>

This way when any TreeView gets selected, ONLY its own TreeViewItemViewModel's IsSelected property will be true and rest all tree view items will be false. So the task left would be to find the selected TreeViewItemViewModel object from the hierarchy of object bound to the ItemsSource of the TreeView.

Way 2:

Have an attached property for a TreeViewItem and handle its MouseDown event. Check if the 'IsSelected' value of the TreeViewItem is true and extract its data context which will be the selected TreeViewItemViewModel.

  <TreeView.Resources>
      <Style TargetType="{x:Type TreeViewItem}">
          <Setter Property="local:MyAttachedBehavior.HandleMouseDown" Value="true" />
      </Style> 
  </TreeView.Resources>

in the static HandleMouseDownPropertyChanged() dependency property changed method, handle the MouseDown event on the (TreeViewItem)sender ...

  ((TreeViewItem)sender).MouseDown += TreeViewMouseDownEventHandler;

  private static TreeViewMouseDownEventHandler(object sender, MouseButtonEventArgs e)
  {
      var treeViewItem = (TreeViewItem)sender;
      if (treeViewItem.IsSelected)
      {
            var mySelectedItem = treeViewItem.DataContext as TreeViewItemViewModel; 
      } 
  }

Pass this selected `TreeViewItemViewModel' instance as the required selected item to your routine.

Let me know if this helps.

Upvotes: 1

Rachel
Rachel

Reputation: 132548

Does the RegionViewModel have access to the StateViewModel? Or more importantly, to StateViewModel.SelectedItem? (Some code would be helpful)

If not, you may have to implement an event system where whenever StateViewModel.SelectedItem changes, it broadcasts a StateChanged event, and RegionViewModel subscribes to that event and keeps track of the SelectedState

Upvotes: 1

Related Questions