Не работают команды контекстного меню

265
09 марта 2017, 20:56

Есть TreeView содержащий данные двух типов. Каждый тип данных имеет своё контекстное меню. К меню привязаны команды, но почему-то они не выполняются.

<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;
    }
}

Несколько часов пытался заставить это работать, но ничего не получилось.

Answer 1

Получилось, но пришлось выкручиваться задавая DataContext через Свойство Tag. Шаблоны изменил так:

 <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>

Сами меню так:

<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>
READ ALSO
форматированный вывод c#

форматированный вывод c#

Как в данную строку вместо f4 - на место 4 подставить переменную в которую будет попадать нужное количество знаков

349
C# работа с базой данных MySQL (подключение)

C# работа с базой данных MySQL (подключение)

Когда пытаюсь подключиться к базе данных - выводит ошибкуКогда я подключаюсь к базе данных из моего компьютера - все нормально, а когда к базе...

593
Asp.Net MVC. Смена сервера во время работы

Asp.Net MVC. Смена сервера во время работы

Проект AspNet MVC, который работает с базой данных MySQl с помощью EF 6

284
Правильная установка пакета nuget C#

Правильная установка пакета nuget C#

ЗдравствуйтеНашел на NuGet бета-версию библиотеки для kinopoisk

307