代码之家  ›  专栏  ›  技术社区  ›  user64718

WPF子菜单样式

  •  8
  • user64718  · 技术社区  · 14 年前

    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/69269d23-f97c-42e3-a9dd-0e7c0ba49bdd?prof=required

    杰伊,这就是我要做的。下面是一些代码,在UserControl.Resources中作为我的对象的顶部。

        <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菜单项本身正确地设置了样式,但是实际的菜单默认为Windows主题样式,到目前为止,我认为没有办法覆盖它。最重要的部分是让子菜单的IsMouseOver保持与主菜单结构相同的外观和感觉。

    3 回复  |  直到 14 年前
        1
  •  20
  •   user64718    14 年前

    正如承诺的,这是密码。谢谢你的帮助,杰伊,带我向正确的方向,最终找到一个答案的MSDN http://msdn.microsoft.com/en-us/library/ms752296.aspx MenuItem和ContextMenu控制基本菜单的样式,另外两个用于子菜单项。杰伊的方法也许奏效了,但不幸的是我没能做到。不过,这非常有效,而且可能允许对子菜单样式进行更多的控制。

        <UserControl.Resources>
    
        <!-- Separator -->
        <Style TargetType="{x:Type Separator}"
               x:Key="SeparatorStyle">
            <Setter Property="Height"
                    Value="1" />
            <Setter Property="Background"
                    Value="#0f3c5a" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Separator}">
                        <Rectangle Height="{TemplateBinding Height}"
                                   Fill="White" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <!--Outer menu items-->
        <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>
    
        <!-- Outer menu -->
        <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"
                                Background="Transparent">
                            <StackPanel ClipToBounds="True"
                                        Orientation="Vertical"
                                        IsItemsHost="True" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver"
                                     Value="true">
                                <Setter TargetName="Border"
                                        Property="Background"
                                        Value="#0f3c5a" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <!-- SubmenuItem -->
    
        <ControlTemplate x:Key="{x:Static MenuItem.SubmenuItemTemplateKey}"
                         TargetType="{x:Type 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" />
                    <Border Name="Check"
                            Width="13"
                            Height="13"
                            Visibility="Collapsed"
                            Margin="6,0,6,0"
                            Background="#0f3c5a"
                            BorderThickness="1"
                            BorderBrush="#5082a4">
                        <Path Name="CheckMark"
                              Width="7"
                              Height="7"
                              Visibility="Hidden"
                              SnapsToDevicePixels="False"
                              Stroke="#5082a4"
                              StrokeThickness="2"
                              Data="M 0 0 L 7 7 M 0 7 L 7 0" />
                    </Border>
                    <ContentPresenter Name="HeaderHost"
                                      Grid.Column="1"
                                      ContentSource="Header"
                                      RecognizesAccessKey="True" />
                    <TextBlock x:Name="InputGestureText"
                               Grid.Column="2"
                               Text="{TemplateBinding InputGestureText}"
                               Margin="5,2,0,2"
                               DockPanel.Dock="Right" />
                </Grid>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="Icon"
                         Value="{x:Null}">
                    <Setter TargetName="Icon"
                            Property="Visibility"
                            Value="Hidden" />
                </Trigger>
                <Trigger Property="IsChecked"
                         Value="true">
                    <Setter TargetName="CheckMark"
                            Property="Visibility"
                            Value="Visible" />
                </Trigger>
                <Trigger Property="IsCheckable"
                         Value="true">
                    <Setter TargetName="Check"
                            Property="Visibility"
                            Value="Visible" />
                    <Setter TargetName="Icon"
                            Property="Visibility"
                            Value="Hidden" />
                </Trigger>
                <Trigger Property="IsHighlighted"
                         Value="true">
                    <Setter TargetName="Border"
                            Property="Background"
                            Value="#5082a4" />
                </Trigger>
                <Trigger Property="IsEnabled"
                         Value="false">
                    <Setter Property="Foreground"
                            Value="#0f3c5a" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    
        <!-- SubmenuHeader -->
    
        <ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}"
                         TargetType="{x:Type 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="#0f3c5a" />
                    <Popup Name="Popup"
                           Placement="Right"
                           HorizontalOffset="-4"
                           IsOpen="{TemplateBinding IsSubmenuOpen}"
                           AllowsTransparency="True"
                           Focusable="False"
                           PopupAnimation="Fade">
                        <Border Name="SubmenuBorder"
                                SnapsToDevicePixels="True"
                                Background="#0f3c5a"
                                BorderBrush="#0f3c5a"
                                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="#5082a4" />
                </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="#0f3c5a" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    
        2
  •  1
  •   Community Dunja Lalic    4 年前

    你是如何运用你的风格的?

    通常,如果在“high”或“outer”元素的资源中定义为style,并且不给它任何键,那么它将应用于下面目标类型的所有项。

    您这样做是看到了意外的行为,还是试图在每个级别定义/应用样式?

    看看你的XAML,我认为问题是你正在设计样式 ContextMenu ,但下面的菜单属于 Menu TargetType 属性 Style . 看看这是否适用于所有级别。如果不是,我会把它改回去再加一个 瞄准 菜单 一个应用于子菜单。

    编辑2

    MenuItem ,这在查看XAML而不是结果时是显而易见的。您在上设置的模板和样式 上下文菜单 也必须设置在任何 菜单项 那是一个子菜单。我尝试了一下,创造了一种针对 菜单项 IsMouseOver 它似乎在做你想做的事。

        3
  •  0
  •   MikNik    12 年前

    为了不复制模板,最好创建一个带有PART\u弹出窗口和子菜单箭头的模板,但是在触发角色为SubmenuHeader之前隐藏错误。