There is a TreeView containing two types of data. Each data type has its own context menu. Commands are attached to the menu, but for some reason they are not executed.

<Window x:Class="WpfApplication4.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApplication4" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:my="clr-namespace:BaseNS" Title="MainWindow" Width="525" Height="350" mc:Ignorable="d"> <Window.Resources> <ContextMenu x:Key="GroupScreenContextMenu"> <MenuItem Command="{Binding DeleteGroupCommand}" Header="Удалить Группу" /> </ContextMenu> <ContextMenu x:Key="ScreenContextMenu" DataContext="{Binding}"> <MenuItem Command="{Binding DeleteScreenCommand}" Header="Удалить экран" /> </ContextMenu> </Window.Resources> <Grid> <TreeView> <TreeView.Resources> <DataTemplate DataType="{x:Type my:ScreenModel}"> <StackPanel ContextMenu="{StaticResource ScreenContextMenu}"> <Label Background="Aqua" Content="{Binding Name}" /> </StackPanel> </DataTemplate> <HierarchicalDataTemplate DataType="{x:Type my:GroupModel}" ItemsSource="{Binding Items}"> <StackPanel ContextMenu="{StaticResource GroupScreenContextMenu}"> <Label Background="Green" Content="{Binding Name}" /> </StackPanel> </HierarchicalDataTemplate> </TreeView.Resources> <TreeViewItem ItemsSource="{Binding Screens}"> <TreeViewItem.Header> <StackPanel> <Label>Screens</Label> </StackPanel> </TreeViewItem.Header> </TreeViewItem> </TreeView> </Grid> 

 public class GroupModel : TreeItemBase { } public class ScreenModel : TreeItemBase { } public class TreeItemBase : INotifyPropertyChanged { private string _Name; public string Name { get { return _Name; } set { _Name = value; OnPropertyChanged("Name"); } } private ObservableCollection<TreeItemBase> _items; public ObservableCollection<TreeItemBase> Items { get { return _items; } set { _items = value; OnPropertyChanged("Items"); } } public class Command : ICommand { private Action _action; public Command(Action p_action) { _action = p_action; } public bool CanExecute(object parameter) { return true; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { if (_action != null) { _action(); } } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName]string prop = "") { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); } } public partial class MainWindow : Window, INotifyPropertyChanged { private ObservableCollection<TreeItemBase> _screens; public ObservableCollection<TreeItemBase> Screens { get { return _screens; } set { _screens = value; OnPropertyChanged("Screens"); } } ICommand DeleteGroupCommand; ICommand DeleteScreenCommand; private void DeleteGroup() { Screens.RemoveAt(0); } private void DeleteScreen() { Screens.RemoveAt(3); } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName]string prop = "") { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); } public MainWindow() { InitializeComponent(); ScreenModel screen = new ScreenModel() { Name = "screen" }; Screens = new ObservableCollection<TreeItemBase>(); Screens.Add(screen); GroupModel screen1 = new GroupModel() { Name = "fld1", Items = new ObservableCollection<TreeItemBase>() { new ScreenModel() { Name = "IP-54" }, new ScreenModel() { Name = "IP-86" } } }; Screens.Add(screen1); GroupModel screen11 = new GroupModel() { Name = "fld2", Items = new ObservableCollection<TreeItemBase>() { new ScreenModel() { Name = "IP-10" }, new ScreenModel() { Name = "IP-38" } } }; Screens.Add(screen11); GroupModel screen111 = new GroupModel() { Name = "fld3", Items = new ObservableCollection<TreeItemBase>() { new ScreenModel() { Name = "IP-92" }, new ScreenModel() { Name = "IP-99" }, new GroupModel() { Name = "fld6", Items = new ObservableCollection<TreeItemBase>() { new ScreenModel() { Name = "IP-55" } } } } }; Screens.Add(screen111); DeleteScreenCommand = new Command(DeleteScreen); DeleteGroupCommand = new Command(DeleteGroup); this.DataContext = this; } } 

A few hours trying to make it work, but nothing happened.

  • one
  • one
  • In general, there are enough solutions, if you search - Ev_Hyper
  • I tried the option using PlacementTarget.Tag, but it did not work for me. Probably because of the HierarchicalDataTemplate, since undefined nesting of elements. - STcoder
  • And the variant with BindingProxy tried? - Ev_Hyper

1 answer 1

It turned out, but I had to get out by setting the DataContext through the Tag Property. Templates changed so:

  <DataTemplate DataType="{x:Type my:ScreenModel}"> <StackPanel ContextMenu="{StaticResource ScreenContextMenu}" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"> <Label Background="Aqua" Content="{Binding Name}" /> </StackPanel> </DataTemplate> <HierarchicalDataTemplate DataType="{x:Type my:GroupModel}" ItemsSource="{Binding Items}" > <StackPanel ContextMenu="{StaticResource GroupScreenContextMenu}" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"> <Label Background="Green" Content="{Binding Name}" /> </StackPanel> </HierarchicalDataTemplate> 

The menus themselves are like this:

 <ContextMenu x:Key="GroupScreenContextMenu" DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.Tag}"> <MenuItem Command="{Binding DeleteGroupCommand}" Header="Удалить Группу"/> </ContextMenu> <ContextMenu x:Key="ScreenContextMenu" DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.Tag}"> <MenuItem Command="{Binding DeleteScreenCommand}" Header="Удалить экран" /> </ContextMenu> 
  • This is exactly what is written on the links that resulted. The fact that you did not immediately work is most likely due to the fact that in the code you gave, the DeleteGroupCommand and DeleteScreenCommand fields and not properties. - Ev_Hyper