当我覆盖DataTemplate时,为什么我的MenuItem有一个Icon?

时间:2015-01-02 18:29:31

标签: wpf xaml datatrigger

我已经成功实现了一个WPF菜单,其中顶级项目被绘制为大按钮,而较低级别项目被绘制为标准菜单项目(请参阅我之前的问题herehere)。

在我原来的尝试中,我的下级项目模板(下例中的SubItemTemplate)包含图像和文本块。结果看起来像一个普通的菜单项,其中有一个空的图标区域和菜单项文本部分中文本旁边的图像。我不希望在视觉显示中看到图标区域,因为我认为整个视觉显示将由我的模板内容决定。顶级模板(TopLevelItemTemplate)没有可见的空图标区域。

当我从较低级别的模板中删除我的图像并将其替换为Icon属性的样式设置器时,我得到了我想要的显示。

我不明白我的低级项DataTemplate上存在Icon属性的方式和原因。

这是我的代码。属性HasParent用于区分不是顶级菜单项(即使用SubItemTemplate绘制的菜单项)。我不太了解的部分是DataTrigger。

为什么触发器内有可用的Icon属性?

<UserControl.Resources>
    <Image x:Key="MenuIconResource16" Height="16" Width="16" Source="{Binding Icon32}" x:Shared="False" />

    <HierarchicalDataTemplate x:Key="TopLevelItemTemplate" ItemsSource="{Binding Children}">
        <StackPanel VerticalAlignment="Bottom" Orientation="Vertical">
            <Image Width="32" Height="32" VerticalAlignment="Center" Source="{Binding Icon32}" ToolTip="{Binding UserHint}" />
            <TextBlock Text="{Binding Name}"/>
        </StackPanel>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate x:Key="SubItemTemplate" ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
</UserControl.Resources>

<WrapPanel Height="Auto">
   <Menu ItemsSource="{Binding DataContext.EventMenu.TopLevel, ElementName=UserControl}" ItemTemplateSelector="{StaticResource MenuItemTemplateSelector}">
       <Menu.ItemContainerStyle>
           <Style TargetType="{x:Type MenuItem}">
               <Setter Property="Command" Value="{Binding Command}" />
               <Setter Property="CommandParameter" Value="{Binding EventType}"/>
               <Style.Triggers>
                   <DataTrigger Binding="{Binding HasParent}" Value="true">
                       <Setter Property="Icon" Value="{StaticResource MenuIconResource16}"/>
                   </DataTrigger>
               </Style.Triggers>
           </Style>
       </Menu.ItemContainerStyle>
   </Menu>
</WrapPanel>

1 个答案:

答案 0 :(得分:1)

  

我认为整个视觉显示将由我的模板内容决定。

@dkozl注意到DataTemplateTemplate之间的区别 - 这是重要的区别。数据模板是拥有控件用作整体控件的一部分的XAML片段,其可以包括或不包括其他(可定制的或硬编码的)可视元素和/或其他数据模板。控件模板是定义控件的可视结构的地方。如果您设置/覆盖控件模板,那么您对未看到任何其他可视内容的期望将成立。

  

顶级模板(TopLevelItemTemplate)没有可见的空图标区域。

此处需要注意的另一件事是Menu的默认样式为其MenuItems定义了多个控件模板。根据角色“TopLevelHeader”,“TopLevelItem”,“SubmenuHeader”和“SubmenuItem”应用这些模板。因此,您将看到这些不同菜单项的不同行为。看看default styles/templates,这应该是有启发性的(尽管它们有点复杂)。

  

为什么触发器内有可用的Icon属性?

样式触发器能够修改应用它的控件的任何依赖项属性。由于相关的样式触发器正在应用于MenuItem控件,因此它可以修改该控件所拥有的Icon dependency property