我正在尝试将ItemsSource
添加到MenuItem
,同时将Command绑定到我的ViewModel(我的Window的DataContext)。到目前为止,我还没有想出办法让它发挥作用。在添加ItemsSource之前,绑定很好。我尝试绑定的集合来自StaticResource
。任何人都可以帮我解决这个问题吗?
<MenuItem Command="{Binding OpenTeamPage}"
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}" />
我尝试过使用它以及它的变体而没有运气:
Command="{Binding OpenTeamPage,
RelativeSource={RelativeSource AncestorType=Window},
Mode=Default}"
如果有人在将我的Command绑定到我的ViewModel时可以告诉我如何使用这个ItemsSource,我将非常感激。我想我可以把Command放在我的Team模型中,但如果可能的话我想避免使用它。
编辑:为了澄清我的问题,使用ItemsSource,ViewModel中的命令根本不会触发。没有ItemsSource,该命令将触发。我希望能够拥有ItemsSource并仍然能够发出命令。
编辑:
public class GameContainer
{
static GameContainer()
{
Teams = new ObservableCollection<Team>();
}
public static ObservableCollection<Team> Teams { get; set; }
}
在App.xaml中:
<data:GameContainer x:Key="Container" />
程序启动时会填充该集合。
一旦我完成这项工作,我的目标就是将选定的团队传递给Viewmodel,希望通过CommandParameter,并显示有关所选团队的信息。
编辑:我在原帖中错了。来自Viewmodel的绑定集合也不起作用。答案 0 :(得分:2)
这是MenuItem
的行为,具有子MenuItem
的项目不会触发Command
,也不应该因为它没有意义。但是,如果您仍想在父项单击上触发命令,则有两个选项
您可以在MenuItem上使用Interactivity Triggers在MouseDown事件上调用命令,如
<MenuItem
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<cmd:EventToCommand Command="{Binding OpenTeamPage}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
您可以为命令定义附加属性并定义MenuItem MouseDown行为,如
public static class MouseCommandBehavior
{
public static readonly DependencyProperty MouseDownCommandProperty =
DependencyProperty.RegisterAttached("MouseDownCommand",
typeof(ICommand),
typeof(MouseCommandBehavior),
new FrameworkPropertyMetadata(null, (obj, e) => OnMouseCommandChanged(obj, (ICommand)e.NewValue, false)));
public static ICommand GetMouseDownCommand(DependencyObject d)
{
return (ICommand)d.GetValue(MouseDownCommandProperty);
}
public static void SetMouseDownCommand(DependencyObject d, ICommand value)
{
d.SetValue(MouseDownCommandProperty, value);
}
private static void OnMouseCommandChanged(DependencyObject d, ICommand command)
{
if (command == null) return;
var element = (FrameworkElement)d;
element.PreviewMouseDown += (obj, e) => command.Execute(null);
}
}
}
您可以在menuItem上设置此属性值
<MenuItem local:MouseCommandBehavior.MouseDownCommand="{Binding OpenTeamPage}"
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}">
答案 1 :(得分:0)
MenuItem
不是叶节点,则不会执行其命令。只有叶子的菜单项(没有子项的项)正在执行命令。
这可能是由于惯例 - 当你点击一个有孩子的物品时你会立刻看到孩子,否则从鼠标悬停到孩子出现的时间会有延迟。
尽管从父母的观点来看,对父母进行命令可能是一个坏主意,但这是可能的:
<MenuItem DisplayMemberPath="Name"
Header="{Binding OpenTeamPage}"
ItemsSource="{Binding Teams, Source={StaticResource Container}}" >
<MenuItem.HeaderTemplate>
<DataTemplate>
<!--Probably need to make this button transparent-->
<Button Content="Teams"
Command="{Binding }"/>
</DataTemplate>
</MenuItem.HeaderTemplate>
<!--This style is for the children to fire the same command as the parent-->
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MenuItem}}, Path=Header}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
根据您的设计,您可能需要将按钮设置为透明样式。