gpt4 book ai didi

wpf - 如何将 ViewModel 的 ObservableCollection 绑定(bind)到 MenuItem?

转载 作者:行者123 更新时间:2023-12-03 15:07:11 28 4
gpt4 key购买 nike

当我将菜单项与 ObservableCollection 绑定(bind)时,只有 MenuItem 的“内部”区域是可点击的:

alt text http://tanguay.info/web/external/mvvmMenuItems.png

在我的查看 我有这个菜单:

<Menu>
<MenuItem
Header="Options" ItemsSource="{Binding ManageMenuPageItemViewModels}"
ItemTemplate="{StaticResource MainMenuTemplate}"/>
</Menu>

然后我用这个 绑定(bind)它数据模板 :
<DataTemplate x:Key="MainMenuTemplate">
<MenuItem
Header="{Binding Title}"
Command="{Binding DataContext.SwitchPageCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Menu}}}"
Background="Red"
CommandParameter="{Binding IdCode}"/>
</DataTemplate>

由于 ObservableCollection 中的每个 ViewModel ManageMenuPageItemViewModels 有房产 职称 身份证号 ,上面的代码乍一看很好用。

然而 ,问题是 菜单项 在 DataTemplate 中实际上是 里面 另一个 MenuItem ( 好像它被绑定(bind)了两次 ) 以便在上面的 DataTemplate 中使用 背景="红色"有一个 每个菜单项内的红色框并且只能单击此区域,而不是整个菜单项区域本身(例如,如果用户单击复选标记所在的区域或内部可单击区域的右侧或左侧,则不会发生任何事情,如果您不这样做' t 有单独的颜色非常困惑。)

将 MenuItems 绑定(bind)到 ViewModel 的 ObservableCollection 以使每个 MenuItem 内的整个区域都可点击的正确方法是什么?

更新:

因此,我根据以下建议进行了以下更改,现在有了:

alt text http://tanguay.info/web/external/mvvmMenuItemsYellow.png

我的 DataTemplate 中只有一个 TextBlock,但我仍然不能“为整个 MenuItem 着色”,只能为 TextBlock:
<DataTemplate x:Key="MainMenuTemplate">
<TextBlock Text="{Binding Title}"/>
</DataTemplate>

我将 Command 绑定(bind)放入 Menu.ItemContainerStyle 但它们现在不触发:
<Menu DockPanel.Dock="Top">
<Menu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Command" Value="{Binding DataContext.SwitchPageCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Menu}}}"/>
<Setter Property="CommandParameter" Value="{Binding IdCode}"/>
</Style>
</Menu.ItemContainerStyle>
<MenuItem
Header="MVVM" ItemsSource="{Binding MvvmMenuPageItemViewModels}"
ItemTemplate="{StaticResource MainMenuTemplate}"/>
<MenuItem
Header="Application" ItemsSource="{Binding ApplicationMenuPageItemViewModels}"
ItemTemplate="{StaticResource MainMenuTemplate}"/>
<MenuItem
Header="Manage" ItemsSource="{Binding ManageMenuPageItemViewModels}"
ItemTemplate="{StaticResource MainMenuTemplate}"/>
</Menu>

最佳答案

我发现将 MVVM 与 MenuItems 一起使用非常具有挑战性。我的应用程序的其余部分使用 DataTemplates 将 View 与 ViewModel 配对,但由于您所描述的原因,这似乎不适用于 Menus。这就是我最终解决它的方法。我的 View 如下所示:

<DockPanel>
<Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=(local:MainViewModel.MainMenu)}">
<Menu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header" Value="{Binding Path=(contracts:IMenuItem.Header)}"/>
<Setter Property="MenuItem.ItemsSource" Value="{Binding Path=(contracts:IMenuItem.Items)}"/>
<Setter Property="MenuItem.Icon" Value="{Binding Path=(contracts:IMenuItem.Icon)}"/>
<Setter Property="MenuItem.IsCheckable" Value="{Binding Path=(contracts:IMenuItem.IsCheckable)}"/>
<Setter Property="MenuItem.IsChecked" Value="{Binding Path=(contracts:IMenuItem.IsChecked)}"/>
<Setter Property="MenuItem.Command" Value="{Binding}"/>
<Setter Property="MenuItem.Visibility" Value="{Binding Path=(contracts:IMenuItem.Visible),
Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Setter Property="MenuItem.ToolTip" Value="{Binding Path=(contracts:IMenuItem.ToolTip)}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(contracts:IMenuItem.IsSeparator)}" Value="true">
<Setter Property="MenuItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator Style="{DynamicResource {x:Static MenuItem.SeparatorStyleKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Menu.ItemContainerStyle>
</Menu>
</DockPanel>

如果您注意到,我定义了一个名为 IMenuItem 的接口(interface),它是 MenuItem 的 ViewModel。这是代码:
public interface IMenuItem : ICommand
{
string Header { get; }
IEnumerable<IMenuItem> Items { get; }
object Icon { get; }
bool IsCheckable { get; }
bool IsChecked { get; set; }
bool Visible { get; }
bool IsSeparator { get; }
string ToolTip { get; }
}

请注意,IMenuItem 定义了 IEnumerable Items,这是您获得子菜单的方式。此外,IsSeparator 是一种在菜单中定义分隔符的方法(另一个棘手的小技巧)。如果 IsSeparator 为真,您可以在 xaml 中看到它如何使用 DataTrigger 将样式更改为现有分隔符样式。下面是 MainViewModel 如何定义 MainMenu 属性( View 绑定(bind)到的):
public IEnumerable<IMenuItem> MainMenu { get; set; }

这似乎运作良好。我假设您可以为 MainMenu 使用 ObservableCollection。我实际上是使用 MEF 将菜单组成部分,但之后项目本身是静态的(即使每个菜单项的属性不是)。我还使用了一个实现 IMenuItem 的 AbstractMenuItem 类,它是一个帮助类来实例化各个部分中的菜单项。

更新:

关于你的颜色问题, this thread帮助?

关于wpf - 如何将 ViewModel 的 ObservableCollection 绑定(bind)到 MenuItem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1067903/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com