当我将模板应用于我的 MenuItem 时,单击时不再显示下拉列表
我有一个 WPF 菜单,我使用控件模板对其进行了样式设置。然后,客户希望在顶级导航项中使用图像而不是文本。
没问题,我为每个顶级项创建了一个控件模板,并在每个 MenuItem 上设置了 Template 属性以匹配自定义模板,如下所示。我有一个触发器可以在翻转时更改图像。
我的问题是,当您单击菜单项时,应该有一个不再下拉的子菜单项。
这些命令针对没有子项的顶级项目触发。一旦我从带有子项的菜单项中删除指定模板的代码,我就会看到带有下拉菜单的文本版本。
我需要做什么才能保留基于图像的顶级菜单项并保留下拉菜单?
提前致谢。
<Menu Grid.Row="0" Grid.Column="0" Name="uxMenu" Margin="0 2 0 0">
<MenuItem Header="Home" Name="uxHome" Command="cmds:NavigationCommands.HomeViewNavigationCommand" Template="{DynamicResource HomeButtonTemplate}"/>
<MenuItem Header="Admin" Name="uxAdmin" Template="{DynamicResource MenuExitButtonTemplate}">
<MenuItem Header="_Setup">
<MenuItem Header="_Overview" Command="cmds:NavigationCommands.MenuAdminSetupOverviewNavigationCommand"/>
<MenuItem Header="_Cameras" Command="cmds:NavigationCommands.MenuAdminSetupCameraNavigationCommand" />
</MenuItem>
</MenuItem>
</Menu>
<ControlTemplate x:Key="HomeButtonTemplate" TargetType="{x:Type MenuItem}">
<Grid >
<Image x:Name="myimage" Source="/Images/Navigation/home_off.png" Width="100" Height="52" />
</Grid>
<ControlTemplate.Triggers >
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter TargetName="myimage" Property="Source" Value="/Images/Navigation/home_on.png" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
为了回应 HB 的帖子...
我确实有一大堆控件模板,我目前正在使用它们来设计我的菜单。因此,如果我想为每个顶级标头指定不同的控制模板,我将必须为每个标头拥有一组全新的控制模板?
我不确定要使用的确切语法,尤其是 x:Key 和 TargetType 属性。
例如。我当前的 TopLevelHeader 和 SubmenuHeader 控件模板代码如下所示。 (从您引用的“menutemplatingpage”复制)
<!-- TopLevelHeader (children)-->
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}" TargetType="MenuItem">
<Border Name="Border">
<Grid>
<ContentPresenter Margin="0 24 0 14" ContentSource="Header" RecognizesAccessKey="True" />
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{StaticResource WindowBackgroundBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1" >
<StackPanel
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter TargetName="Popup" Property="PopupAnimation" Value="None"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="false">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter TargetName="Border" Property="Background" Value="Transparent"/>
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent"/>
<Setter TargetName="Border" Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="#fff"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter TargetName="Border" Property="Background" Value="Transparent"/>
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent"/>
<Setter TargetName="Border" Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="0,0,4,4"/>
<Setter TargetName="SubmenuBorder" Property="Padding" Value="10"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- SubmenuHeader -->
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}" TargetType="MenuItem">
<Border Name="Border" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Shortcut"/>
<ColumnDefinition Width="13"/>
</Grid.ColumnDefinitions>
<ContentPresenter
Name="Icon"
Margin="6,0,6,0"
VerticalAlignment="Center"
ContentSource="Icon"/>
<ContentPresenter
Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True"/>
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Text="{TemplateBinding InputGestureText}"
Margin="5,2,2,2"
DockPanel.Dock="Right"/>
<Path
Grid.Column="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 0 7 L 4 3.5 Z"
Fill="{StaticResource GlyphBrush}" />
<Popup
Name="Popup"
Placement="Right"
HorizontalOffset="-4"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{StaticResource WindowBackgroundBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1" >
<StackPanel
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="4"/>
<Setter TargetName="SubmenuBorder" Property="Padding" Value="0,3,0,3"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
因此,如果我使用“HomeButtonTemplate”键添加新的控制模板(如帖子顶部附近所示),我将必须添加一个新部分(以及所有其他 ControlTemplates 用于 SubmenuItem 等。
这些新的 ControlTemplates 如何知道它们属于同一组控件模板?
谢谢您提供的任何建议。
I had a WPF menu which I'd styled using control templates. Then the client wanted to use images instead of text for the Top Level navigation items.
No problem, I created a control template for each top-level item and set my Template attribute on each MenuItem to match the custom template like the one below. I've a Trigger that changes the image on rollover.
My problem is that when you click on the Menu Item that should have a sub-menu items that they no longer drop-down.
The commands fire for the Top-level items that don't have children. And as soon as I remove my code specifying the template from my Menu Item with children I see the text version with the drop-down.
What do I need to do to keep my image-based top-level menu item and keep my drop-downs?
Thanks in advance.
<Menu Grid.Row="0" Grid.Column="0" Name="uxMenu" Margin="0 2 0 0">
<MenuItem Header="Home" Name="uxHome" Command="cmds:NavigationCommands.HomeViewNavigationCommand" Template="{DynamicResource HomeButtonTemplate}"/>
<MenuItem Header="Admin" Name="uxAdmin" Template="{DynamicResource MenuExitButtonTemplate}">
<MenuItem Header="_Setup">
<MenuItem Header="_Overview" Command="cmds:NavigationCommands.MenuAdminSetupOverviewNavigationCommand"/>
<MenuItem Header="_Cameras" Command="cmds:NavigationCommands.MenuAdminSetupCameraNavigationCommand" />
</MenuItem>
</MenuItem>
</Menu>
<ControlTemplate x:Key="HomeButtonTemplate" TargetType="{x:Type MenuItem}">
<Grid >
<Image x:Name="myimage" Source="/Images/Navigation/home_off.png" Width="100" Height="52" />
</Grid>
<ControlTemplate.Triggers >
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter TargetName="myimage" Property="Source" Value="/Images/Navigation/home_on.png" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
In response to H.B's post...
I do have a big ol' set of control templates that I'm currently using to style my menu. So if I want to specify a different control template for each of my top level headers I'm going to have to have an entirely new set of control templates for each one?
I'm unsure of the exact syntax to use, especially for the x:Key and TargetType attributes.
For example. My current code looks like this for my TopLevelHeader and SubmenuHeader control templates. (Copied from the 'menutemplatingpage' you reference')
<!-- TopLevelHeader (children)-->
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}" TargetType="MenuItem">
<Border Name="Border">
<Grid>
<ContentPresenter Margin="0 24 0 14" ContentSource="Header" RecognizesAccessKey="True" />
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{StaticResource WindowBackgroundBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1" >
<StackPanel
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter TargetName="Popup" Property="PopupAnimation" Value="None"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="false">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter TargetName="Border" Property="Background" Value="Transparent"/>
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent"/>
<Setter TargetName="Border" Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="#fff"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter TargetName="Border" Property="Background" Value="Transparent"/>
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent"/>
<Setter TargetName="Border" Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="0,0,4,4"/>
<Setter TargetName="SubmenuBorder" Property="Padding" Value="10"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- SubmenuHeader -->
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}" TargetType="MenuItem">
<Border Name="Border" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Shortcut"/>
<ColumnDefinition Width="13"/>
</Grid.ColumnDefinitions>
<ContentPresenter
Name="Icon"
Margin="6,0,6,0"
VerticalAlignment="Center"
ContentSource="Icon"/>
<ContentPresenter
Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True"/>
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Text="{TemplateBinding InputGestureText}"
Margin="5,2,2,2"
DockPanel.Dock="Right"/>
<Path
Grid.Column="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 0 7 L 4 3.5 Z"
Fill="{StaticResource GlyphBrush}" />
<Popup
Name="Popup"
Placement="Right"
HorizontalOffset="-4"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{StaticResource WindowBackgroundBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1" >
<StackPanel
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="4"/>
<Setter TargetName="SubmenuBorder" Property="Padding" Value="0,3,0,3"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
So if I add my new Control template with the key of "HomeButtonTemplate" as shown near the top of my post I'm going to have to add a new section (as well as all the other ControlTemplates for things like SubmenuItem etc.
How do these new ControlTemplates know that they belong to the same group of control templates? I feel I'm not asking this correctly.
Thanks for any advice you can give.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您通过指定自己的模板来完全删除现有模板(相当复杂),您的模板不再提供必要的功能。控件模板中有一个名为
PART_Popup
的部件,用于显示子项。检查此页面中的链接(
默认 WPF 主题),您可以在其中下载包含模板的默认样式,以查看模板的外观。
另请查看菜单模板页面,它应该会给您一个想法菜单模板有多复杂。
You completely remove the existing template (which is fairly complex) by specifying your own, your template no longer provides the necessary functionality. There is a part in the control template indentified with the name
PART_Popup
, which is used to display sub-items.Check this page for a link (
Default WPF themes
) where you can download the default styles which include the templates to see what your template should look like.Also have a look at the menu templating page which should give you an idea just how complex templating the menu is.
这可能有点晚了,但我最近遇到了同样的问题。
对我有用的是
在
ControlTemplate
内的Border
内创建一个像这样的 StackPanel。给你留下一些与此类似的东西。
This might be a bit late but I recently had the same issue.
What worked for me was to create a StackPanel like so
inside the
Border
which is inside theControlTemplate
.Leaving you with something along the lines of this.