TabControl 上的 WPF 上下文菜单 header

WPF Context menu on TabControl header

我有一个 TabControl 并将其 ItemSource 绑定到 ObserverableCollection 视图模型。我还将其 DataTemplate 设置为与视图模型关联的视图。

这很好用,在 ItemContainerStyle 中我添加了一个 ContextMenu,其中有一个 MenuItem。如何在我的代码中触发 MenuItems click 事件?我无法参加 Delete_OnClick 中的活动。此外,发件人应该是对绑定到 TabControlItemSource 的视图模型的引用。

    <TabControl ItemsSource="{Binding MyTabItems}">

        <TabControl.Resources>
            <DataTemplate DataType="{x:Type viewModels:MyTabItemViewModel}">
                <views:MyTabItem/>
            </DataTemplate>
        </TabControl.Resources>

        <TabControl.ItemContainerStyle>
            <Style TargetType="{x:Type TabItem}">
                <Setter Property="Header" Value="{Binding Path=Header}"/>
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu>
                            <MenuItem Header="Delete" Click="Delete_OnClick"/>
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </Style>
        </TabControl.ItemContainerStyle>

    </TabControl>


    // In code behind I have this method that should be triggered when the
    // Delete MenuItem is clicked
    private void Delete_OnClick(object sender, RoutedEventArgs e)
    {
        var tabItem = (ITabItem) sender;
        ViewModel.DeleteTab(tabItem);
    }

总结:我可以右键单击选项卡 header 并单击“删除”,但我没有从中获得任何事件。

我大大改变了原来的答案。

我的理解是你使用了MVVM模式。如果是这样,您不应该直接使用事件处理程序。相反,您应该将菜单项绑定到命令。

<ContextMenu>
    <MenuItem Header="Delete" Command={Binding MyCommand} />
</ContextMenu>

MyCommand 应该是在 MyTabItemViewModel class.

中定义的 属性
public class MyTabItemViewModel 
{
    public ICommand MyCommand { get; set; }
    ...
}

MyCommand 属性 可以 return 实现 ICommand interface. It can be a predefined command (for example see ApplicationCommands class) 或您自己的任何 class 的实例。这是您的 DeleteCommand 的示例:

public class DeleteCommand: ICommand
{
    private ParentVM Parent { get; set; }
    private MyTabItemViewModel Item { get; set; }

    public MyCustomCommand (ParentVM parent, MyTabItemViewModel item)
    {
        Parent= parent;
        Item = item;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        parent.RemoveItem(item);
    }

    ...
}

我假设你的带有 MyTabItems 集合的视图模型被称为 ParentVM 并且它有一个 public 方法 RemoveItem 负责删除给定的项目从这个集合。

您可以在MyTabItemViewModel的构造函数中实例化DeleteCommand。例如:

public class MyTabItemViewModel 
{
    public ICommand MyCommand { get; set; }

    public MyTabItemViewModel(ParentVM parent)
    {
        MyCommand = new DeleteCommand(parent, this);
    }

    ...
}

改为使用 EventSetter,这应该适用于您的情况

<Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu>
                            <MenuItem Header="Delete" >
                                <MenuItem.Style>
                                    <Style TargetType="MenuItem">
                                        <EventSetter Event="Click" Handler="Delete_OnClick"/>
                                    </Style>
                                </MenuItem.Style>
                            </MenuItem>
                        </ContextMenu>
                    </Setter.Value>
                </Setter>