WPF: TreeViewItem bound to an ICommand

Richard picture Richard · Feb 15, 2010 · Viewed 15.8k times · Source

I am busy creating my first MVVM application in WPF.

Basically the problem I am having is that I have a TreeView (System.Windows.Controls.TreeView) which I have placed on my WPF Window, I have decide that I will bind to a ReadOnlyCollection of CommandViewModel items, and these items consist of a DisplayString, Tag and a RelayCommand.

Now in the XAML, I have my TreeView and I have successfully bound my ReadOnlyCollection to this. I can view this and everything looks fine in the UI.

The issue now is that I need to bind the RelayCommand to the Command of the TreeViewItem, however from what I can see the TreeViewItem doesn't have a Command. Does this force me to do it in the IsSelected property or even in the Code behind TreeView_SelectedItemChanged method or is there a way to do this magically in WPF?

This is the code I have:

<TreeView BorderBrush="{x:Null}" 
      HorizontalAlignment="Stretch" 
      VerticalAlignment="Stretch">
<TreeView.Items>
    <TreeViewItem
        Header="New Commands"
        ItemsSource="{Binding Commands}"
        DisplayMemberPath="DisplayName"
        IsExpanded="True">
    </TreeViewItem>
</TreeView.Items>

and ideally I would love to just go:

<TreeView BorderBrush="{x:Null}" 
      HorizontalAlignment="Stretch" 
      VerticalAlignment="Stretch">
<TreeView.Items>
    <TreeViewItem
        Header="New Trade"
        ItemsSource="{Binding Commands}"
        DisplayMemberPath="DisplayName"
        IsExpanded="True"
        Command="{Binding Path=Command}">
    </TreeViewItem>
</TreeView.Items>

Does someone have a solution that allows me to use the RelayCommand infrastructure I have.

Thanks guys, much appreciated!

Richard

Answer

Shaggy13spe picture Shaggy13spe · Feb 4, 2011

I know this was "answered" a while ago, but since the answers weren't ideal, I figured I'd put in my two cents. I use a method that allows me to not have to resort to any "styled button trickery" or even using code-behind and instead keeps all my separation in MVVM. In your TreeView add the following xaml:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectedItemChanged">
        <i:InvokeCommandAction Command="{Binding TreeviewSelectedItemChanged}" CommandParameter="{Binding ElementName=treeView, Path=SelectedItem}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

In your xaml header add:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

and then you'll have to add a reference to the above assembly in your project.

After that, everything acts just the same as any other command would on say a button or something.