为什么我的 MenuItem 在我覆盖了 DataTemplate 后有一个图标?
Why does my MenuItem have an Icon when I have overridden the DataTemplate?
我已经成功地实现了一个 WPF 菜单,其中顶级项目被绘制为大按钮,而较低级别的项目被绘制为标准菜单项(参见我之前的问题 here and here)。
在我最初的尝试中,我的低级项目模板(下例中的 SubItemTemplate
)包含一个图像和一个文本块。结果是一个看起来像普通菜单项的东西,它有一个空的图标区域和菜单项文本部分中文本旁边的图像。我没想到会在视觉显示中看到图标区域,因为我认为整个视觉显示将由我的模板内容决定。顶级模板 (TopLevelItemTemplate
) 没有任何可见的空白图标区域。
当我从较低级别的模板中删除我的图像并将其替换为 Icon 属性的样式设置器时,我得到了我想要的显示。
我不明白 Icon 属性如何以及为何存在于我的较低级别的项目 DataTemplate 上。
这是我的代码。属性 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>
I thought that the entire visual display would be determined by the contents of my template.
@dkozl 指出了 DataTemplate
和 Template
之间的区别——这是重要的区别。数据模板是拥有控件用作整体控件一部分的 XAML 片段,它可能包含也可能不包含其他(可自定义或硬编码)可视元素,and/or 其他数据模板。控件模板是定义控件视觉结构的地方。如果您 set/override 一个控件模板,那么您对看不到任何其他可视内容的期望将成立。
The top-level template (TopLevelItemTemplate
) does not have any empty icon area visible.
这里要注意的另一件事是 Menu
的默认样式为其 MenuItems
定义了多个控件模板。根据角色 "TopLevelHeader"、"TopLevelItem"、"SubmenuHeader" 和 "SubmenuItem" 应用这些模板。因此,您会看到这些不同菜单项的不同行为。看看 default styles/templates,它应该很有启发性(尽管它们有点复杂)。
Why is there an Icon property available inside that trigger?
样式触发器能够修改应用它的控件的任何依赖项属性。由于所讨论的样式触发器正在应用于 MenuItem
控件,它可以修改属于该控件的 Icon
dependency property。
我已经成功地实现了一个 WPF 菜单,其中顶级项目被绘制为大按钮,而较低级别的项目被绘制为标准菜单项(参见我之前的问题 here and here)。
在我最初的尝试中,我的低级项目模板(下例中的 SubItemTemplate
)包含一个图像和一个文本块。结果是一个看起来像普通菜单项的东西,它有一个空的图标区域和菜单项文本部分中文本旁边的图像。我没想到会在视觉显示中看到图标区域,因为我认为整个视觉显示将由我的模板内容决定。顶级模板 (TopLevelItemTemplate
) 没有任何可见的空白图标区域。
当我从较低级别的模板中删除我的图像并将其替换为 Icon 属性的样式设置器时,我得到了我想要的显示。
我不明白 Icon 属性如何以及为何存在于我的较低级别的项目 DataTemplate 上。
这是我的代码。属性 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>
I thought that the entire visual display would be determined by the contents of my template.
@dkozl 指出了 DataTemplate
和 Template
之间的区别——这是重要的区别。数据模板是拥有控件用作整体控件一部分的 XAML 片段,它可能包含也可能不包含其他(可自定义或硬编码)可视元素,and/or 其他数据模板。控件模板是定义控件视觉结构的地方。如果您 set/override 一个控件模板,那么您对看不到任何其他可视内容的期望将成立。
The top-level template (
TopLevelItemTemplate
) does not have any empty icon area visible.
这里要注意的另一件事是 Menu
的默认样式为其 MenuItems
定义了多个控件模板。根据角色 "TopLevelHeader"、"TopLevelItem"、"SubmenuHeader" 和 "SubmenuItem" 应用这些模板。因此,您会看到这些不同菜单项的不同行为。看看 default styles/templates,它应该很有启发性(尽管它们有点复杂)。
Why is there an Icon property available inside that trigger?
样式触发器能够修改应用它的控件的任何依赖项属性。由于所讨论的样式触发器正在应用于 MenuItem
控件,它可以修改属于该控件的 Icon
dependency property。