1

I have a TreeView filled with items of my custom type ToolbarTreeItem. Now when the user clicks on an item, I want to know which item was clicked in the MainViewModel.

I want to achieve this without code behind, but with a RelayCommand.

So how do I pass the selected item to the RelayCommand without having to use a standard event, which leads to code behind?

Code-snippet in MainViewModel.cs:

private ToolbarTreeItem _selectedItem;

private RelayCommand<ToolbarTreeItem> _changeSelectedItem;
public RelayCommand<ToolbarTreeItem> ChangeSelectedItem
{
    get
    {
        return _changeSelectedItem ?? (_changeSelectedItem = new RelayCommand<ToolbarTreeItem>(selectedItem =>
       {
           _selectedItem = selectedItem;
       }));
    }
}

Xaml-snippet in Toolbar.xaml:

<TreeView SelectedItemChanged="???" />
RUL
  • 268
  • 2
  • 12
  • @ASh, but I don't have this property available in Xaml, only when accessing the `TreeView` in code. – RUL Jun 27 '18 at 12:04
  • Behaviors, converters do they also count to code-behind in your opinion? – Rekshino Jun 27 '18 at 12:11
  • @Rekshino, no, but do you know, that with either one of those it will be possible? – RUL Jun 27 '18 at 12:17
  • Sure! In behavior you have access on each event and property of TreeView. And you can any time attach this behavior in xaml – Rekshino Jun 27 '18 at 12:19
  • @Rekshino, Behaviors actually sound good, but to stay simple, i might as well stick to using a quick standard event, that sets the property directly on the ViewModel. Thank you! – RUL Jun 27 '18 at 12:25
  • 1
    Possible duplicate of [Data binding to SelectedItem in a WPF Treeview](https://stackoverflow.com/questions/1000040/data-binding-to-selecteditem-in-a-wpf-treeview) – dymanoid Jun 27 '18 at 12:25

1 Answers1

0

Behavior:

public class TreeViewSelection : Behavior<TreeView>
{
    public static readonly DependencyProperty CurrentSelectionProperty = DependencyProperty.Register("CurrentSelection", typeof(object), typeof(TreeViewSelection), new PropertyMetadata(default(object)));

    public object CurrentSelection
    {
        get
        {
            return (object)GetValue(CurrentSelectionProperty);
        }
        set
        {
            SetValue(CurrentSelectionProperty, value);
        }
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.SelectedItemChanged += TreeView_SelectedItemChanged;
    }

    private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        CurrentSelection = e.NewValue;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.SelectedItemChanged -= TreeView_SelectedItemChanged;
    }
}


XAML:

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

<TreeView ...>
    <i:Interaction.Behaviors>
        <b:TreeViewSelection  CurrentSelection = "{Binding VMSelection}" />
    </i:Interaction.Behaviors>
</TreeView>
Rekshino
  • 6,954
  • 2
  • 19
  • 44