WPF 子菜单样式
如果我向菜单项添加子菜单,则子菜单的样式不正确。此时只能设置菜单项的样式,而不能设置实际的子菜单的样式。因此,无法替换 IsMouseOver
样式,该样式默认为 Windows 上启用的任何主题。
如何设计子菜单的样式?
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Background" Value="#0f3c5a"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Style.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" Value="Black"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="LightGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<!--Here is where you change the border thickness to zero on the menu-->
<Border BorderThickness="0" x:Name="Border" >
<StackPanel ClipToBounds="True" Orientation="Vertical"
IsItemsHost="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="#5082a4" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后像这样的菜单
<ContextMenu Closed="ContextMenu_Closed" >
<MenuItem Command="k:Window1.NewCommand" >
<MenuItem Command="k:Window1.DeleteCommand"/>
</MenuItem>
...
NewCommand 层上的所有内容都设置了正确的样式,进入 NewCommand 来查看 DeleteCommand MenuItem 本身的样式设置正确,但实际的菜单默认为 Windows 主题样式,我看不出有什么办法可以覆盖它,所以远的。最重要的部分是让子菜单的 IsMouseOver 保持与主菜单结构相同的外观和感觉。
If I add a submenu to a menu item, then the submenu is not being styled properly. One can only style the menuitem at this point, and not the actual sub menu. Hence one can't replace the IsMouseOver
styling which then just defaults to whatever theme is enabled on windows.
How can one style the submenu?
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Background" Value="#0f3c5a"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Style.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" Value="Black"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="LightGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<!--Here is where you change the border thickness to zero on the menu-->
<Border BorderThickness="0" x:Name="Border" >
<StackPanel ClipToBounds="True" Orientation="Vertical"
IsItemsHost="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="#5082a4" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and then something like this for the menu
<ContextMenu Closed="ContextMenu_Closed" >
<MenuItem Command="k:Window1.NewCommand" >
<MenuItem Command="k:Window1.DeleteCommand"/>
</MenuItem>
...
Everything on the NewCommand layer is styled properly, going inside NewCommand to view DeleteCommand the MenuItem itself is styled properly, but the actual menu is defaulting to the Windows theme styling and I see no way over overwriting that so far. The most important part is to get the IsMouseOver of submenu's to maintain the same look and feel as the main menu structure.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如所承诺的,这是代码。感谢您的帮助 Jay,引导我朝着正确的方向最终在 MSDN 上找到答案 http://msdn.microsoft.com/en-us/library/ms752296.aspx MenuItem 和ContextMenu 控制基本菜单的样式,另外两个用于子菜单项。杰伊的方法也许有效,但不幸的是我没能实现。不过,这工作得很好,并且可能允许对子菜单样式进行更多控制。
As promised, here's the code. Thanks for your help Jay, lead me in the right direction to finally find an answer on MSDN http://msdn.microsoft.com/en-us/library/ms752296.aspx MenuItem and ContextMenu control the styling for the base menu, and the other two are for the submenu items. Jay's way may have worked, but I couldn't get it to unfortunately. This works perfectly though, and probably allows for much more control over the submenus styling.
你如何应用你的风格?
通常,如果您在“high”或“outer”元素的资源中定义样式,并且不给它任何键,则它将应用于下面目标类型的所有项目。
您是否在执行此操作并看到意外行为,或者您是否尝试在每个级别内嵌定义/应用样式?
编辑 1
查看您的 XAML,我认为问题在于您正在设计
ContextMenu
样式,但下面的菜单是Menu
类型。我尝试的第一件事是将Style
的TargetType
属性更改为Menu
。看看这是否适用于所有级别。如果没有,我会将其改回来并添加另一个针对Menu
的Style
并查看该样式是否应用于子菜单。编辑2
好吧,我想我已经得到你的答案了。子菜单实际上是一个
MenuItem
,这在查看 XAML 而不是结果时是显而易见的。您在ContextMenu
上设置的模板和样式也必须在作为子菜单的任何MenuItem
上设置。我尝试了一下,并创建了一个以MenuItem
为目标的样式,带有控件模板和IsMouseOver
触发器,它似乎可以完成您正在尝试的操作。How are you applying your styles?
Typically, if you define as style in a "high" or "outer" element's Resources, and give it no key, it will apply to all items of the target type below.
Are you doing this and seeing unexpected behaviour, or are you attempting to define/apply styles in-line at each level?
edit 1
Looking at your XAML, I think the issue is that you are styling
ContextMenu
, but menus below that are of typeMenu
. The first thing I'd try is to just change theTargetType
attribute for theStyle
toMenu
. See if that gets applied at all levels. If not, I'd change it back and add anotherStyle
targetingMenu
and see if that one gets applied to the submenu.edit 2
Okay, I think I've got your answer. The submenu is actually a
MenuItem
, which is obvious when looking at the XAML instead of the result. The template and styling that you're setting on theContextMenu
must also be set on anyMenuItem
that is a submenu. I tried it out and created a style that targetsMenuItem
with a control template and trigger forIsMouseOver
and it appeared to do what you're trying.为了不重复模板,您最好创建一个同时包含 PART_Popup 和子菜单箭头的模板,但隐藏错误,直到您被 Role 为 SubmenuHeader 触发为止。
To not duplicate the templates, you're better off creating one with both PART_Popup and arrow for the submenu, but hide the error until you're triggered with Role being SubmenuHeader.