动态绑定到 Window 的 MenuItem 上的 ViewModel 命令
使用 MVVM 结构开发 WPF 应用程序。
我的窗口显示菜单和当前的 ViewModel。在菜单的 MenuItem 之一上,我想列出当前 ViewModel 中找到的一些命令。菜单中列出的命令将根据 ViewModel 的不同而变化。
我让它工作得很好,但样式很混乱 - 命令菜单项位于另一个菜单框或其他东西内。我将附上屏幕截图。
我将 ViewModel 的 ICommand 对象(在本例中为 RelayCommands)包装在 CommandViewModel 中,它公开了我想要在菜单上显示的命令和显示字符串。这些 CommandViewModel 位于列表中:CurrentWorkspace.AdditionalOptionsCommands
。
这是菜单的 XAML。就像我说的,它有效,它显示了正确的项目并且命令被执行。显示不正确 - 谁能告诉我原因以及如何修复它?请参阅屏幕截图。
<Menu>
<MenuItem Header="_Additional Options..." ItemsSource="{Binding Path=CurrentWorkspace.AdditionalOptionsCommands}">
<MenuItem.ItemTemplate>
<DataTemplate DataType="{x:Type vm:CommandViewModel}">
<MenuItem Header="{Binding Path=DisplayText}" Command="{Binding Path=Command}"/>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem Header="_Testing">
<MenuItem Header="This looks right" />
<MenuItem Header="This looks right" />
</MenuItem>
</Menu>
当前外观:
所需外观:
Working on a WPF application using the MVVM structure.
My Window displays a menu and the current ViewModel. On one of the Menu's MenuItems, I want to list some Commands found in the current ViewModel. The commands listed in the Menu will change depending on the ViewModel.
I got this to work just fine, but the style is messed up - the Command MenuItems are inside another menu box or something. I'll attach a screenshot.
I wrapped the ViewModel's ICommand objects (RelayCommands, in this instance) in CommandViewModel, which expose the Command and the Display string I want on the menu. These CommandViewModels are in a list: CurrentWorkspace.AdditionalOptionsCommands
.
Here is the XAML for the Menu. Like I said, it works, it shows the right items and the commands are executed. The display is just incorrect - can anybody tell me why and how to fix it? See the screenshot.
<Menu>
<MenuItem Header="_Additional Options..." ItemsSource="{Binding Path=CurrentWorkspace.AdditionalOptionsCommands}">
<MenuItem.ItemTemplate>
<DataTemplate DataType="{x:Type vm:CommandViewModel}">
<MenuItem Header="{Binding Path=DisplayText}" Command="{Binding Path=Command}"/>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem Header="_Testing">
<MenuItem Header="This looks right" />
<MenuItem Header="This looks right" />
</MenuItem>
</Menu>
Current Appearance:
Desired Appearance:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为当您通过
ItemsSource
指定菜单项时,每个项目都会自动包装到MenuItem
对象中。这样,DataTemplate
(MenuItem
元素)中定义的内容将被包装到另一个MenuItem
中。您需要做的不是定义
DataTemplate
,而是为MenuItem
定义一种样式,在其中设置与视图模型属性的绑定,并将该样式用作ItemContainerStyle父
:MenuItem
上的请参阅 http://drwpf.com/blog/2008/03/25/itemscontrol -i-is-for-item-container/ 有关项目容器如何与
ItemsControl
控件配合使用的深入说明。This is because when you specify menu items via
ItemsSource
each item gets automatically wrapped into aMenuItem
object. This way the content defined in theDataTemplate
(MenuItem
element) gets wrapped into one moreMenuItem
.What you need to do instead of defining a
DataTemplate
is to define a style for theMenuItem
where you setup bindings to the view model's properties and use this style asItemContainerStyle
on the parentMenuItem
:See http://drwpf.com/blog/2008/03/25/itemscontrol-i-is-for-item-container/ for an in-depth explanation on how item containers work with
ItemsControl
controls.