(1)Menu的ItemContainerStyle属性,设计的是Menu中最末层的MenuItem(即本身没有子级菜单)的样式;
对以下2种MenuItem无效:
(a)对最顶级的MenuItem无效,如图最顶端的后面2个MenuItem(这2个MenuItem下面没有子MenuItem);
(b)对自身含有子级菜单的MenuItem无效,如图菜单1的第一个MenuItem含有一个子级MenuItem;
ItemContainerStyle="{StaticResource Menu_MenuItemStyle}"
为了让MenuItem模板能根据不同层级的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>