Reputation: 5384
I'm a newbie to TreeViews. In WPF style, I have a TreeView organized in three levels:
ReportName1
NetworkName1
PrinterName1
PrinterName2
NetworkName2
PrinterName3
PrinterName4
ReportName2
....
in the XAML, I am using Interaction behaviors to bind the TreeView SelectedItem to the ViewModel:
<TreeView ItemsSource="{Binding ReportTree}" >
<i:Interaction.Behaviors>
<tvb:TreeViewBehavior SelectedItem="{Binding SelectedTreeItem, Mode=TwoWay}" />
</i:Interaction.Behaviors>
At this point, all works well to send an item from the ReportTree when I select ANY item under the main report name. That is, if I select PrinterName2, then the SelectedTreeItem will be the main viewmodel for ReportName1.
What I need to know is, how can I tell that PrinterName2 is selected as opposed to PrinterName1?
My eventual goal is to allow selection of any leaf or branch in the tree and remove only that selected leaf or branch.
Is there a way to do this?
Thanks for any help on this.
Upvotes: 1
Views: 284
Reputation: 13184
Here is one option to solve this using a simple DataTemplate
for the TreeView which contains a MouseBinding
to call a select command on the parent ViewModel and pass the clicked item as a CommandParameter
.
If your ViewModel looks something like this:
public class MainViewModel
{
public ObservableCollection<ItemViewModel> Items { get; private set; }
public ItemViewModel SelectedItem { get; set; }
public ICommand SelectItem { get; private set; }
public MainViewModel()
{
SelectItem = new LazyCommand<ItemViewModel>(ExecuteSelect);
Items = new ObservableCollection<ItemViewModel>();
}
private void ExecuteSelect(ItemViewModel item)
{
SelectedItem = item;
}
}
with a straightforward ViewModel for the items:
public class ItemViewModel
{
public ObservableCollection<ItemViewModel> Items { get; private set; }
public string Name { get; set; }
public ItemViewModel()
{
Items = new ObservableCollection<ItemViewModel>();
}
}
Then you can define a TreeView with an HierarchicalDataTemplate
as ItemTemplate
:
<TreeView ItemsSource="{Binding Items}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}" >
<TextBlock Text="{Binding Name}">
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftClick"
Command="{Binding DataContext.SelectItem, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding}" />
</TextBlock.InputBindings>
</TextBlock>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
The crucial part is the binding to the TreeViews DataContext.SelectItemCommand from the MouseBinding of each item and passing the item in as a parameter. You can then handle the selection itself (setting SelectedItem
, etc.) in the ViewModel.
Upvotes: 1