WPF模型绑定菜单,在顶层和其他级别具有不同的ItemContainerStyle [英] WPF model-bound menu with different ItemContainerStyle at top level and other levels

查看:85
本文介绍了WPF模型绑定菜单,在顶层和其他级别具有不同的ItemContainerStyle的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个动态WPF菜单,其外观与顶级项目和后续级别项目不同.特别是,我希望我的顶级项目在菜单标题的顶部显示一个32像素的正方形图像,随后的项目在常规的Icon位置显示一个16像素的图像. (我发布了相关问题,几天前,有人在使用模板而不是样式.

I am attempting to construct a dynamic WPF menu with different appearance for the top level items and the subsequent level items. In particular, I would like my top level items to display a 32 pixel square image on top of the menu caption, and the subsequent items to display a 16 pixel image in the regular Icon location. (I posted a related question some days ago, that one was using templates instead of styles).

下面的XAML代码产生具有以下特征的菜单:

The XAML code below produces a menu with the following characteristics:

.所有菜单项都绑定到并显示32像素的图标,这使我相信仅使用了第二个ItemContainerStyle(参考资料"部分中的一个 not ).

. All menu items bind to and display the 32 pixel icon, leading me to believe that only the second ItemContainerStyle is being used (the one not in the Resources section).

. Command和CommandParameter属性正确绑定.当我单击菜单项时,将执行命令.

. The Command and CommandParameter properties bind correctly; when I click a menu item the command is executed.

.名称属性未正确绑定 ,所有标头均为空字符串.在输出"窗口中,不会为此属性生成任何绑定错误.

. The Name property is not bound correctly, all Headers are empty strings. No binding errors are generated for this property in the Output window.

.网格中给出的模板信息(应该应用于顶层项目)永远不会呈现.

. The template information given in the Grid (which is supposed to apply to the top-level items) is never rendered.

基于这个示例我认为部分问题可能是我必须将XAML树中的资源"移到WrapPanel上.但是,执行此操作时,无法在菜单中找到StaticResources.

Based on this example I believe that part of the problem may be that I have to move my Resources higher in the XAML tree, to the WrapPanel. When I do this, however, the StaticResources cannot be located in the menu.

如何修改菜单,以对顶层项目和其他项目应用不同的样式(或模板-我不挑剔!)?

How can I modify my menu to apply different styles (or templates -- I'm not picky!) to the top-level items and the other items?

<WrapPanel Height="Auto">
    <Menu ItemsSource="{Binding DataContext.EventMenu.TopLevel, ElementName=UserControl}">
        <Menu.Resources>
            <Image x:Key="MenuIconResource16" Height="16" Width="16" Source="{Binding Icon16}" x:Shared="False" />
            <Image x:Key="MenuIconResource32" Height="32" Width="32" Source="{Binding Icon32}" x:Shared="False" />
            <HierarchicalDataTemplate x:Key="SubItemStyle" ItemsSource="{Binding Children}">
                <HierarchicalDataTemplate.ItemContainerStyle>
                    <Style TargetType="{x:Type MenuItem}">
                        <Setter Property="IsEnabled" Value="true"/>
                        <Setter Property="Command" Value="{Binding Command}" />
                        <Setter Property="CommandParameter" Value="{Binding EventType}"/>
                        <Setter Property="Header" Value="{Binding Name}"/>
                        <Setter Property="Icon" Value="{StaticResource MenuIconResource16}"/>
                        <!--<Setter Property="ItemsSource" Value="{Binding Children}"/>-->
                    </Style>
                </HierarchicalDataTemplate.ItemContainerStyle>
            </HierarchicalDataTemplate>
        </Menu.Resources>
        <Menu.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <HierarchicalDataTemplate.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="IsEnabled" Value="true"/>
                    <Setter Property="Command" Value="{Binding Command}" />
                    <Setter Property="CommandParameter" Value="{Binding EventType}"/>
                    <Setter Property="Header" Value="{Binding Name}"/>
                    <Setter Property="Icon" Value="{StaticResource MenuIconResource32}"/>
                    <!--<Setter Property="ItemsSource" Value="{Binding Children}"/>-->
                    <Setter Property="ItemTemplate" Value="{StaticResource SubItemStyle}"></Setter>
                </Style>
            </HierarchicalDataTemplate.ItemContainerStyle>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Image Grid.Row="0" Width="32" Height="32" VerticalAlignment="Center" Source="{Binding Icon32}"/>
                <TextBlock Grid.Row="1" Text="{Binding Name}"/>
            </Grid>
        </HierarchicalDataTemplate>
        </Menu.ItemTemplate>
    </Menu>
</WrapPanel>

推荐答案

您似乎混淆了ItemContainerStyle,它是Style与可以在ItemTemplate属性中使用的DataTemplate.前者是容器Style,或者在您的情况下是MenuItem,而实际数据项应使用DataTemplate定义.

You seem to have confused the ItemContainerStyle, which is a Style with a DataTemplate that could be used in the ItemTemplate property. The former is the Style for the container, or in your case the MenuItem, whereas the actual data items should be defined with a DataTemplate.

您只需使用DataTemplate s和

You could achieve your requirements just using DataTemplates and a DataTemplateSelector, ignoring the ItemContainerStyle for now. This method would require you to declare one DataTemplate for the normal items and another for each variation that you want. You would then use the DataTemplateSelector.SelectTemplate method to decide which DataTemplate to apply to each MenuItem.

此示例摘自MSDN上的链接页面,并演示了如何使用DataTemplateSelector:

This example is taken from the linked page on MSDN and demonstrates how you can use the DataTemplateSelector:

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
    FrameworkElement element = container as FrameworkElement;

    if (element != null && item != null && item is Task)
    {
        Task taskitem = item as Task;

        if (taskitem.Priority == 1)
            return
                element.FindResource("importantTaskTemplate") as DataTemplate;
        else 
            return
                element.FindResource("myTaskTemplate") as DataTemplate;
    }

    return null;
}

这篇关于WPF模型绑定菜单,在顶层和其他级别具有不同的ItemContainerStyle的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆