0

I've got a WPF MultiSelectTreeView (downloaded from here: http://unclassified.software/en/source/multiselecttreeview).

Now I want to control, which items the user selects. A simple example is that he shouldn't be able to select child nodes of different parents. But there are also more ViewModel-specific use cases.

It's easy to achieve this in code-behind of the Window by using the PreviewSelectionChanged event, checking the conditions directly and setting the Cancel-flag accordingly. But since I want to obtain the separation of View and ViewModel, I am looking for a way of doing this in my WindowViewModel.

Of course you could also extract the check to the ViewModel and call it from the view, but it looks wrong:

WindowViewModel _viewModel;

void PreviewSelectionChanged(object sender, PreviewSelectionChangedEventArgs e)
{
     e.Cancel = !this._viewModel.CanSelect(e.Item as TreeItemViewModel);
}

I hope that anybody has an idea.

- timnot90

timnot90
  • 351
  • 1
  • 13
  • Separation of View / Logic does not mean no code behind in your view classes. You don't lose testability of your ViewModels by using PreviewSelectionChanged, so in my opinion it's fine. – metacircle Feb 23 '15 at 09:01
  • 2
    Typically, your data items should have an `IsSelected` property that you data bind to the `TreeViewItem.IsSelected` property. Then you can just set that to `true` to select an item and to `false` to deselect an item. – Sheridan Feb 23 '15 at 09:06
  • @Sheridan Yes they have. But I have no idea when to set this property. If I do it in code behind, I can also do it the way I described in my question. And since it seems to be okay, I think I will. I just thought that there is some kind of fancy, extraordinary way of doing this in mvvm. Thanks for your help. Just one more thing: what can I do to mark this question as answered with no "real" answer available? – timnot90 Feb 23 '15 at 09:49

1 Answers1

0

Typically, when data binding a hierarchical collection to a TreeView in WPF, the custom data items should have an IsSelected property defined in their class. If they do, then it can be data bound to the IsSelected property of each TreeViewItem:

<TreeView ItemsSource="{Binding YourCollection}" ... >
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

When this is done, you can just set that property to true to select an item and to false to deselect an item.

// Select Item
dataObject.IsSelected = true;

// Deselect Item
dataObject.IsSelected = false;

You can add a handler to the PropertyChanged event of each item to detect when the IsSelected property changes (if they implement the INotifyPropertyChanged interface as expected).

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • I implemented an IsSelectedChanged event in the ViewModel of the data items now and it's working perfectly. Thanks a lot. – timnot90 Feb 23 '15 at 13:17