动态绑定到 Window 的 MenuItem 上的 ViewModel 命令

发布于 2024-11-10 10:04:50 字数 1268 浏览 3 评论 0原文

使用 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:

Current Appearance

Desired Appearance:

Desired Appearance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心意如水 2024-11-17 10:04:50

这是因为当您通过 ItemsSource 指定菜单项时,每个项目都会自动包装到 MenuItem 对象中。这样,DataTemplateMenuItem 元素)中定义的内容将被包装到另一个 MenuItem 中。

您需要做的不是定义 DataTemplate ,而是为 MenuItem 定义一种样式,在其中设置与视图模型属性的绑定,并将该样式用作 ItemContainerStyle父 MenuItem 上的

<Window.Resources>
    <Style x:Key="CommandMenuItemStyle"
           TargetType="{x:Type MenuItem}">
         <Setter Property="Header"
                 Value="{Binding Path=DisplayText}"/> 
         <Setter Property="Command"
                 Value="{Binding Path=Command}"/>
    </Style>
</Window.Resources>
...
<Menu>
    <MenuItem Header="_Additional Options..." 
              ItemsSource="{Binding Path=CurrentWorkspace.AdditionalOptionsCommands}" 
              ItemContainerStyle="{StaticResource CommandMenuItemStyle}"/>
    <MenuItem Header="_Testing">
        <MenuItem Header="This looks right" />
        <MenuItem Header="This looks right" />
    </MenuItem>   
</Menu>   

请参阅 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 a MenuItem object. This way the content defined in the DataTemplate (MenuItem element) gets wrapped into one more MenuItem.

What you need to do instead of defining a DataTemplate is to define a style for the MenuItem where you setup bindings to the view model's properties and use this style as ItemContainerStyle on the parent MenuItem:

<Window.Resources>
    <Style x:Key="CommandMenuItemStyle"
           TargetType="{x:Type MenuItem}">
         <Setter Property="Header"
                 Value="{Binding Path=DisplayText}"/> 
         <Setter Property="Command"
                 Value="{Binding Path=Command}"/>
    </Style>
</Window.Resources>
...
<Menu>
    <MenuItem Header="_Additional Options..." 
              ItemsSource="{Binding Path=CurrentWorkspace.AdditionalOptionsCommands}" 
              ItemContainerStyle="{StaticResource CommandMenuItemStyle}"/>
    <MenuItem Header="_Testing">
        <MenuItem Header="This looks right" />
        <MenuItem Header="This looks right" />
    </MenuItem>   
</Menu>   

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文