20

我有一个上下文菜单。它绑定到某个集合,并且它具有如下定义的 ItemTemplate:

<ContextMenu
    ItemsSource={Binding ...}
    ItemTemplate={StaticResource itemTemplate}
    />

itemTemplate 是一个带有 TextBlock 的简单 DataTemplate:

<DataTemplate x:Key="itemTemplate">
    <TextBlock Text={Binding ...} />
</DataTemplate>

如何将 MenuItem 的 Command 属性绑定到基础对象的属性?

4

3 回答 3

25

我认为您需要将 TextBlock 包装在 MenuItem 中:

<DataTemplate x:Key="itemTemplate">
    <MenuItem Command={Binding ...}>
        <TextBlock Text={Binding ...} />
    </MenuItem>
</DataTemplate>

但是我现在没有 IDE 来尝试这个。让我知道事情的后续。


看起来您需要使用这里看到的 ItemContainerStyle 。很抱歉一开始就让你走错了路——但我在一个 IDE 前面,这很有效:

<ContextMenu.ItemContainerStyle>
    <Style TargetType="MenuItem">
        <Setter Property="Command" Value="{Binding ...}"/>
    </Style>
</ContextMenu.ItemContainerStyle>
于 2009-05-22T16:56:38.727 回答
6

虽然这只是马丁哈里斯答案的微小变化,但我想我还是会分享它。我发现为整个集合指定单个命令并发送命令参数更有用:

<MenuItem.ItemContainerStyle>
    <Style TargetType="MenuItem">
       <Setter Property="Command" Value="{x:Static v:ViewModel.CommandForAll}"/>
       <Setter Property="CommandParameter" Value="{Binding ValueForCommand}"/>
    </Style>
</MenuItem.ItemContainerStyle>

然后您可以确定在该命令的处理程序中要做什么:

private void CommandForAll_Executed(object sender, ExecutedRoutedEventArgs e)
{
    var cmdParam = e.Paramater as ExpectedType
    if (cmdParam != null)
        //DoStuff...
}
于 2012-05-04T19:33:41.867 回答
0

我意识到我在事后回答了这个问题,但我遇到了同样的问题,以前的答案似乎使绑定到多个不同的命令变得困难。我到达的解决方案与 MatrixManAtYrService 非常相似,分为 3 个部分:

1)使用 ItemContainerStyle 属性将命令绑定到 ViewModel 中的命令——这与前面的答案相同。一个例外是我将 CommandParameter 绑定到 MenuItem。

<Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource Self}}"/>

2) 创建一个自定义类来定义每个 MenuItem 的外观和行为。菜单的 ItemsSource 将设置为这些列表。这与其他答案相同。但是,在我的实现中,我为类提供了一个 Action,以便在调用 MenuItemCommand 时执行。我还包括了一个允许禁用 MenuItem 的布尔值。

public class MenuAction
{
    public string Name { get => name; set => name = value; }
    public Action Action { get => action; set => action = value; }
    public bool CanExecute { get => canExecute; set => canExecute = value; }
}

3) 在命令执行路由控制到MenuAction 中的代表。

public void HandleCommand(object sender)
{
    MenuItem clickedMenuItem = sender as MenuItem;
    MenuAction menuAction = clickedMenuItem?.DataContext as MenuAction;
    if(menuAction != null)
        menuAction.Action();
}

public bool CanMenuItemExecute(object sender)
{
    MenuItem clickedMenuItem = sender as MenuItem;
    MenuAction menuAction = clickedMenuItem?.DataContext as MenuAction;
    if (menuAction != null)
        return menuAction.CanExecute;
    else
        return false;
}

这应该允许您在列表中定义命令的所有行为。虽然它在技术上绑定到单个命令,但它在功能上类似于拥有多个不同的命令。同样的方法也应该适用于嵌套的 MenuItems 和 HierarchicalDataTemplates 并进行一些调整。

于 2019-12-03T07:30:29.263 回答