(1)Menu的ItemContainerStyle属性,设计的是Menu中最末层的MenuItem(即本身没有子级菜单)的样式;

  对以下2种MenuItem无效:

    (a)对最顶级的MenuItem无效,如图最顶端的后面2个MenuItem(这2个MenuItem下面没有子MenuItem);

    (b)对自身含有子级菜单的MenuItem无效,如图菜单1的第一个MenuItem含有一个子级MenuItem;  

  ItemContainerStyle="{StaticResource Menu_MenuItemStyle}"

  

wpfMenuItem菜单中点击打钩 wpf menu_wpfMenuItem菜单中点击打钩

根据不同层级的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的背景色。

  

wpfMenuItem菜单中点击打钩 wpf menu_文字颜色_02

(4) Menu的ItemTemplate属性,设计的是所有Item的模板,和MenuItem所在的层级无关。

      本例中,将ItemTemplate背景色设置为紫色,CornerRadius=5.

     

wpfMenuItem菜单中点击打钩 wpf menu_文字颜色_03

 

(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>