(1)Menu的ItemContainerStyle属性,设计的是Menu中最末层的MenuItem(即本身没有子级菜单)的样式;
对以下2种MenuItem无效:
(a)对最顶级的MenuItem无效,如图最顶端的后面2个MenuItem(这2个MenuItem下面没有子MenuItem);
(b)对自身含有子级菜单的MenuItem无效,如图菜单1的第一个MenuItem含有一个子级MenuItem;
ItemContainerStyle="{StaticResource Menu_MenuItemStyle}"
根据不同层级的MenuItem自动分配布局,可以用下面几个属性,放在Trigger里面:
<ControlTemplate.Triggers>
<!-- Role = TopLevelHeader : 菜单中的根级的menuitem,且这个menuitem有子级菜单-->
<!-- Role = TopLevelHeader : this is the root menu item in a menu; the Popup expands up -->
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Padding" Value="6,1,10,1"/>
<Setter Property="Placement" Value="Top" TargetName="SubMenuPopup"/>
<Setter Property="MinWidth" Value="0" TargetName="Col0"/>
<Setter Property="Width" Value="Auto" TargetName="Col3"/>
<Setter Property="CornerRadius" Value="0,20,0,0" TargetName="Border"/>
<!--<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>-->
<Setter Property="Visibility" Value="Collapsed" TargetName="GlyphPanel"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="IGTHost"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<!-- Role = TopLevelItem : 菜单中的根级menuitem,且这个menuitem没有子级菜单-->
<!-- Role = TopLevelItem : this is a child menu item from the top level without any child items-->
<Trigger Property="Role" Value="TopLevelItem">
<!--<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>-->
<Setter Property="Padding" Value="6,1,10,1"/>
<Setter Property="Placement" Value="Top" TargetName="SubMenuPopup"/>
<Setter Property="MinWidth" Value="0" TargetName="Col0"/>
<Setter Property="Width" Value="Auto" TargetName="Col3"/>
<Setter Property="CornerRadius" Value="0,20,0,0" TargetName="Border"/>
<!--<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>-->
<Setter Property="Visibility" Value="Collapsed" TargetName="GlyphPanel"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="IGTHost"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<!-- Role = SubMenuHeader : 菜单中的子级menuitem,且这个menuitem有子级菜单 -->
<!-- Role = SubMenuHeader : this is a child menu item which does not have children -->
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="0,2,0,2"/>
</Trigger>
<!-- Role = SubMenuItem : 菜单中的子级menuitem,且这个menuitem没有子级菜单-->
<!-- Role = SubMenuItem : this is a child menu item which has children-->
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="0,2,0,2"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<!-- IsSuspendingPopupAnimation : 获取菜单是否挂起对其 Popup 控件的动画 -->
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" Value="None" TargetName="SubMenuPopup"/>
</Trigger>
<!-- If no Icon is present the we collapse the Icon Content -->
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
</Trigger>
<!-- Icon和checkmark在Grid的同一列中,一般做法是:如果checkmark的显示优先级高于Icon,所以此处将Icon隐藏 -->
<!-- The GlyphPanel contains the CheckMark -->
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" Value="Visible" TargetName="GlyphPanel"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
</Trigger>
<!-- IsHighlighted : 鼠标移动或键盘导航到MenuItem上-->
<!-- Using the system colors for the Menu Highlight and IsEnabled-->
<Trigger Property="IsHighlighted" Value="true">
<Setter Property="Foreground" Value="Gold"/>
<Setter Property="Background" TargetName="Border" Value="{DynamicResource MouseOnBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
(2)Menu的ItemsPanel属性,设计的是Menu中所有ItemsPanel的样式,和MenuItem所在的层级无关:
ItemsPanel="{StaticResource Menu_ItemsPanelTemplate}"
见上图,ItemsPanel被设计成倾斜的效果,每个MenuItem所在的panel都呈现了倾斜效果(见上图)。
(3) 当设置了ItemsPanel内的panel的背景色时(暗黄色),只有最顶级的背景颜色发生了变化,并且会覆盖掉Menu的背景色。
(4) Menu的ItemTemplate属性,设计的是所有Item的模板,和MenuItem所在的层级无关。
本例中,将ItemTemplate背景色设置为紫色,CornerRadius=5.
(5)非常全的的各级MenuItem的设置,直接看代码以及注释。
1 <Style x:Key="MLB_Separator" TargetType="{x:Type Separator}">
2 <Setter Property="Margin" Value="0,3,0,3" />
3 <Setter Property="Template">
4 <Setter.Value>
5 <ControlTemplate TargetType="{x:Type Separator}">
6 <Grid>
7 <Rectangle Height="1" Stroke="#efefef" />
8 <!--分割线颜色和menu的文字颜色一样-->
9 <!--<Rectangle Height="1" Stroke="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}" />-->
10 </Grid>
11 </ControlTemplate>
12 </Setter.Value>
13 </Setter>
14 </Style>
15 <Style x:Key="MLB_MenuItem" TargetType="{x:Type MenuItem}">
16 <Setter Property="Foreground" Value="White" />
17 <Setter Property="FontWeight" Value="Bold"/>
18 <Setter Property="Background" Value="{DynamicResource NormalBrush}"/>
19 <!--MenuItem文字颜色和menu的文字颜色一样-->
20 <!--<Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}"/>-->
21 <Setter Property="Template">
22 <Setter.Value>
23 <ControlTemplate TargetType="{x:Type MenuItem}">
24 <Border x:Name="Border"
25 BorderBrush="{TemplateBinding BorderBrush}"
26 BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Height="{TemplateBinding Height}">
27 <Grid>
28 <Grid.ColumnDefinitions>
29 <ColumnDefinition x:Name="Col0" SharedSizeGroup="MenuItemIconColumnGroup" MinWidth="17" Width="Auto"/>
30 <ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
31 <ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
32 <ColumnDefinition x:Name="Col3" Width="14"/>
33 </Grid.ColumnDefinitions>
34
35 <!-- ContentPresenter to show an Icon if needed -->
36 <ContentPresenter Grid.Column="0"
37 Margin="4,0,6,0" x:Name="Icon"
38 VerticalAlignment="Center" ContentSource="Icon"/>
39
40 <!-- Glyph is a checkmark if needed for a checkable menu -->
41 <Grid Grid.Column="0" Visibility="Visible" Margin="4,0,6,0" x:Name="GlyphPanel" VerticalAlignment="Center">
42 <!--<Path x:Name="GlyphPanelpath" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}"
43 Data="M0,2 L0,4.8 L2.5,7.4 L7.1,2.8 L7.1,0 L2.5,4.6 z" FlowDirection="LeftToRight"/>-->
44 <Path x:Name="GlyphPanelpath" HorizontalAlignment="Right" VerticalAlignment="Center"
45 Fill="{TemplateBinding Foreground}" Data="M0,0 L0,8 L4,4 z"/>
46 </Grid>
47
48 <!-- Content for the menu text etc -->
49 <ContentPresenter Grid.Column="1"
50 Margin="{TemplateBinding Padding}"
51 x:Name="HeaderHost"
52 RecognizesAccessKey="True"
53 VerticalAlignment="Center"
54 ContentSource="Header"/>
55
56 <!-- Content for the menu IGT -->
57 <ContentPresenter Grid.Column="2"
58 Margin="8,1,8,1"
59 x:Name="IGTHost"
60 ContentSource="InputGestureText"
61 VerticalAlignment="Center" Visibility="Collapsed"/>
62
63 <!-- Arrow drawn path which points to the next level of the menu -->
64 <Grid Grid.Column="3" Margin="4,0,6,0" x:Name="ArrowPanel" VerticalAlignment="Center">
65 <Path x:Name="ArrowPanelPath" HorizontalAlignment="Right" VerticalAlignment="Center"
66 Fill="{TemplateBinding Foreground}" Data="M0,0 L0,8 L4,4 z"/>
67 </Grid>
68
69 <!-- The Popup is the body of the menu which expands
70 down or across depending on the level of the item -->
71 <Popup IsOpen="{Binding Path=IsSubmenuOpen,
72 RelativeSource ={RelativeSource TemplatedParent}}"
73 Placement="Right" x:Name="SubMenuPopup" Focusable="false"
74 PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}">
75 <Border x:Name="SubMenuBorder" BorderBrush="{Binding Path=Foreground,
76 RelativeSource={RelativeSource AncestorType={x:Type Menu}}}"
77 BorderThickness="1" Padding="2,2,2,2">
78 <Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True">
79 <!-- StackPanel holds children of the menu. This is set by IsItemsHost=True -->
80 <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
81 </Grid>
82 </Border>
83 </Popup>
84 </Grid>
85 </Border>
86
87 <!-- These triggers re-configure the four arrangements
88 of MenuItem to show different levels of menu via Role -->
89 <ControlTemplate.Triggers>
90 <!-- Role = TopLevelHeader : 菜单中的根级的menuitem,且这个menuitem有子级菜单-->
91 <!-- Role = TopLevelHeader : this is the root menu item in a menu; the Popup expands up -->
92 <Trigger Property="Role" Value="TopLevelHeader">
93 <Setter Property="Padding" Value="6,1,10,1"/>
94 <Setter Property="Placement" Value="Top" TargetName="SubMenuPopup"/>
95 <Setter Property="MinWidth" Value="0" TargetName="Col0"/>
96 <Setter Property="Width" Value="Auto" TargetName="Col3"/>
97 <Setter Property="CornerRadius" Value="0,20,0,0" TargetName="Border"/>
98 <!--<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>-->
99 <Setter Property="Visibility" Value="Collapsed" TargetName="GlyphPanel"/>
100 <Setter Property="Visibility" Value="Collapsed" TargetName="IGTHost"/>
101 <Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
102 </Trigger>
103
104 <!-- Role = TopLevelItem : 菜单中的根级menuitem,且这个menuitem没有子级菜单-->
105 <!-- Role = TopLevelItem : this is a child menu item from the top level without any child items-->
106 <Trigger Property="Role" Value="TopLevelItem">
107 <!--<Setter Property="Padding" Value="6,1,6,1"/>
108 <Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>-->
109
110 <Setter Property="Padding" Value="6,1,10,1"/>
111 <Setter Property="Placement" Value="Top" TargetName="SubMenuPopup"/>
112 <Setter Property="MinWidth" Value="0" TargetName="Col0"/>
113 <Setter Property="Width" Value="Auto" TargetName="Col3"/>
114 <Setter Property="CornerRadius" Value="0,20,0,0" TargetName="Border"/>
115 <!--<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>-->
116 <Setter Property="Visibility" Value="Collapsed" TargetName="GlyphPanel"/>
117 <Setter Property="Visibility" Value="Collapsed" TargetName="IGTHost"/>
118 <Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
119 </Trigger>
120
121 <!-- Role = SubMenuHeader : 菜单中的子级menuitem,且这个menuitem有子级菜单 -->
122 <!-- Role = SubMenuHeader : this is a child menu item which does not have children -->
123 <Trigger Property="Role" Value="SubmenuHeader">
124 <Setter Property="DockPanel.Dock" Value="Top"/>
125 <Setter Property="Padding" Value="0,2,0,2"/>
126 </Trigger>
127
128 <!-- Role = SubMenuItem : 菜单中的子级menuitem,且这个menuitem没有子级菜单-->
129 <!-- Role = SubMenuItem : this is a child menu item which has children-->
130 <Trigger Property="Role" Value="SubmenuItem">
131 <Setter Property="DockPanel.Dock" Value="Top"/>
132 <Setter Property="Padding" Value="0,2,0,2"/>
133 <Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
134 </Trigger>
135
136 <!-- IsSuspendingPopupAnimation : 获取菜单是否挂起对其 Popup 控件的动画 -->
137 <Trigger Property="IsSuspendingPopupAnimation" Value="true">
138 <Setter Property="PopupAnimation" Value="None" TargetName="SubMenuPopup"/>
139 </Trigger>
140
141 <!-- If no Icon is present the we collapse the Icon Content -->
142 <Trigger Property="Icon" Value="{x:Null}">
143 <Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
144 </Trigger>
145
146 <!-- Icon和checkmark在Grid的同一列中,一般做法是:如果checkmark的显示优先级高于Icon,所以此处将Icon隐藏 -->
147 <!-- The GlyphPanel contains the CheckMark -->
148 <Trigger Property="IsChecked" Value="true">
149 <Setter Property="Visibility" Value="Visible" TargetName="GlyphPanel"/>
150 <Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
151 </Trigger>
152
153 <!-- IsHighlighted : 鼠标移动或键盘导航到MenuItem上-->
154 <!-- Using the system colors for the Menu Highlight and IsEnabled-->
155 <Trigger Property="IsHighlighted" Value="true">
156 <Setter Property="Foreground" Value="Gold"/>
157 <Setter Property="Background" TargetName="Border" Value="{DynamicResource MouseOnBrush}"/>
158 </Trigger>
159
160 <Trigger Property="IsEnabled" Value="false">
161 <Setter Property="Foreground" Value="Gray"/>
162 </Trigger>
163 </ControlTemplate.Triggers>
164 </ControlTemplate>
165 </Setter.Value>
166 </Setter>
167 </Style>