WPF模型绑定菜单,顶层和其他级别具有不同的ItemContainerStyle

时间:2014-12-18 16:50:37

标签: wpf xaml hierarchicaldatatemplate

我正在尝试为顶级项目和后续级别项目构建一个具有不同外观的动态WPF菜单。特别是,我希望我的顶级项目在菜单标题的顶部显示32像素的正方形图像,以及后续项目在常规图标位置显示16像素的图像。 (几天前我发布了一个related question,一个是使用模板而不是样式。)

下面的XAML代码会生成一个具有以下特征的菜单:

。所有菜单项都绑定并显示32像素图标,这使我相信只使用了第二个ItemContainerStyle(参考资料部分中的不是)。

。 Command和CommandParameter属性绑定正确;当我点击一个菜单项时,命令就会被执行。

。 Name属性绑定正确,所有标题都是空字符串。在“输出”窗口中没有为此属性生成绑定错误。

表示Grid中给出的模板信息(应该应用于顶级项目)。

基于this example我认为问题的一部分可能是我必须将我的资源在XAML树中更高地移动到WrapPanel。但是,当我这样做时,StaticResources不能位于菜单中。

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

<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>

1 个答案:

答案 0 :(得分:3)

您似乎混淆了ItemContainerStyleStyleDataTemplate可以在ItemTemplate属性中使用。前者是容器Style,或者是MenuItem,而实际数据项应使用DataTemplate定义。

您只需使用DataTemplateDataTemplateSelector即可达到您的要求,暂时忽略ItemContainerStyle。此方法要求您为正常项目声明一个DataTemplate,为您想要的每个变体声明另一个。{1}}。然后,您可以使用DataTemplateSelector.SelectTemplate方法来确定应用于DataTemplate的{​​{1}}。

此示例取自MSDN上的链接页面,演示了如何使用MenuItem

DataTemplateSelector