views:

673

answers:

1

I have a requirement in which a menu should be implemented as a treeview on the left side of a window.

I know how to populate the treeview with the (menu)data (the mvvm way).

But: how do i hook up each object in the treeview to an ICommand (in the Viewmodel)?? so that e.g. double clicking an object results in opening a window??

Thanks in advance

A: 

I think this problem should be solved in another way but...

  • You would have the command on your view model as a property.
  • You derive from treeview and treeview item.
  • You give the treeview item a command property, you bind this to your view model's command in the tree views itemContainerStyle (in the xaml)
  • You override the preview mouse down on the tree view item to call the command

here is a sample TreeViewItem

   public class EditableTreeViewItem : TreeViewItem {

      public ICommand DoubleClickCommand {
         get { return (ICommand)GetValue(DoubleClickCommandProperty); }
         set { SetValue(DoubleClickCommandProperty, value); }
      }

      // Using a DependencyProperty as the backing store for DoubleClickCommand.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty DoubleClickCommandProperty =
          DependencyProperty.Register("DoubleClickCommand", typeof(ICommand), typeof(EditableTreeView), new UIPropertyMetadata(null));



      protected override void OnPreviewMouseDoubleClick(MouseButtonEventArgs e) {

         if (this.DoubleClickCommand!= null) {
            this.DoubleClickCommand.Execute(this.DataContext);
            e.Handled = true;
         }
         base.OnPreviewMouseDoubleClick(e);
      }

      protected override DependencyObject GetContainerForItemOverride() {
         return new EditableTreeViewItem();
      }

      protected override bool IsItemItsOwnContainerOverride(object item) {
         return item is EditableTreeViewItem;
      }
}

and a treeview to use this item

 public class EditableTreeView : TreeView {

      //generate the tree view item
      protected override DependencyObject GetContainerForItemOverride() {
         EditableTreeViewItem item = new EditableTreeViewItem();
         return item;
      }

      protected override bool IsItemItsOwnContainerOverride(object item) {
         return item is EditableTreeViewItem;
      }
}

now as some smart people have said above, you would be better off using a menu and styling it. now when you double click the treeview item it will call the command instead of expanding/collapsing as it should.

this is how you would use it in the xaml

         <controls:EditableTreeViewMode=OneWayToSource}"
             ItemsSource="{Binding Path=MyItemsSource}">
             <controls:EditableTreeView.ItemContainerStyle>
                <!-- This Style binds a TreeViewItem to a the ViewModel. -->
                <Style
                   TargetType="{x:Type controls:EditableTreeViewItem}">
                   <Setter
                      Property="DoubleClickCommand"
                      Value="{Binding OpenNewWindowCommand}" />
                </Style>
             </controls:EditableTreeView.ItemContainerStyle>
          </controls:EditableTreeView>
Aran Mulholland
...to be honest: never thought about doing it this way!! though i have used similar approach in other fields! Sounds very interesting and 'll give it a try. Thanks very much for opening a blinds man eyes!
Savvas Sopiadis