我有一个上下文菜单。它绑定到某个集合,它有一个定义的ItemTemplate,如下所示:
<ContextMenu
ItemsSource={Binding ...}
ItemTemplate={StaticResource itemTemplate}
/>
itemTemplate是一个带有TextBlock的简单DataTemplate:
<DataTemplate x:Key="itemTemplate">
<TextBlock Text={Binding ...} />
</DataTemplate>
如何将MenuItem的Command属性绑定到底层对象的属性?
答案 0 :(得分:24)
我认为你需要将TextBlock包装在MenuItem中:
<DataTemplate x:Key="itemTemplate">
<MenuItem Command={Binding ...}>
<TextBlock Text={Binding ...} />
</MenuItem>
</DataTemplate>
但我现在没有在我面前试用这个IDE。让我知道它是怎么回事。
看起来您需要使用ItemContainerStyle,如here所示。很抱歉在开始的时候引导你走错了道路 - 但是我在IDE前面就可以了,这很有效:
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding ...}"/>
</Style>
</ContextMenu.ItemContainerStyle>
答案 1 :(得分:6)
虽然这只是Martin Harris的答案的一个微小变化,但我认为无论如何我都会分享它。我发现更有用的是为整个集合指定一个命令,并且还发送一个CommandParameter:
<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...
}
答案 2 :(得分:0)
我意识到我在事实之后回答了很多,但是我遇到了同样的问题,以前的回答似乎使绑定到多个不同的命令变得困难。我到达的解决方案与MatrixManAtYrService的解决方案非常相似,并且分为三个部分:
1)使用ItemContainerStyle属性将命令绑定到ViewModel中的命令-这与前面的答案相同。一个例外是我将CommandParameter绑定到MenuItem。
<Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource Self}}"/>
2)创建一个自定义类,以定义每个MenuItem的外观和行为。菜单的ItemsSource将设置为这些列表。这与其他答案相同。但是,在我的实现中,我给了类一个在调用MenuItemCommand时要执行的Action。我还包含一个布尔值,该布尔值将允许禁用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也可以通过一些调整来使用相同的方法。