【问题标题】:WPF - MenuItem highlighting has unwanted secondary highlightWPF - 菜单项突出显示有不需要的次要突出显示
【发布时间】:2013-05-29 21:22:48
【问题描述】:

我在Button 上有一个ContextMenu,当它显示时会显示菜单项列表,这很好。如果我将鼠标移到菜单中的某个项目上,它会突出显示,但当我将鼠标悬停在文本上方和周围时,我也会获得次要突出显示,请参见下面的图片。

如何删除它?我尝试了所有类型的样式、触发器和各种其他模板来删除突出显示,但似乎无法正常工作或显示。

我的上下文菜单按钮也没有什么特别之处,请参见下面的 wpf。

<Button.ContextMenu>
    <ContextMenu ItemsSource="{Binding SelectedTreeItem.MetaTargets}">
        <ContextMenu.ItemTemplate>
            <DataTemplate >
                <MenuItem Header="{Binding Name}"
                          Command="{Binding Path=SelectedTreeItem.AddTargetCommandRelay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
                          CommandParameter="{Binding}"
                 />
            </DataTemplate>
        </ContextMenu.ItemTemplate>
    </ContextMenu>
</Button.ContextMenu>

理想情况下,我希望它在突出显示时看起来像这样,无论鼠标在突出显示项目范围内的哪个位置,请参见下图。

【问题讨论】:

  • 尝试将 Windows 主题设置为经典,这将帮助您确认这是来自“默认”Aero 风格,还是来自您自己的风格。
  • 我已经在使用经典了,而且我根本没有将任何自己的样式应用于控件。
  • 我也在运行 Windows 8

标签: wpf button wpf-controls contextmenu highlighting


【解决方案1】:

我对 ContextMenu 实例使用以下样式。显然你可以改变颜色以适应。

<Style x:Key="ContextMenuStyle"  TargetType="{x:Type ContextMenu}">
    <Setter Property="Background" Value="LightBlue"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ContextMenu}">
                <Border BorderThickness="1"
                        BorderBrush="LightBlue">
                    <StackPanel IsItemsHost="True"
                                Background="{TemplateBinding Background}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

编辑:

如果这不起作用,您也可以重新设置 MenuItem 的样式。这是一个例子:

    <ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}"
                     TargetType="MenuItem">
        <Border Name="Border" >
            <Grid>
                <ContentPresenter  Margin="6,3,6,3" 
                                   ContentSource="Header"
                                   RecognizesAccessKey="True" />
                <Popup Name="Popup"
                       Placement="Bottom"
                       IsOpen="{TemplateBinding IsSubmenuOpen}"
                       AllowsTransparency="True" 
                       Focusable="False"
                       PopupAnimation="Fade">
                    <Border Name="SubmenuBorder"
                            SnapsToDevicePixels="True"
                            Background="#FF2D2D30"
                            BorderBrush="#FF2D2D30"
                            BorderThickness="1" >
                        <StackPanel IsItemsHost="True" 
                                    KeyboardNavigation.DirectionalNavigation="Cycle" />
                    </Border>
                </Popup>
            </Grid>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsSuspendingPopupAnimation" Value="true">
                <Setter TargetName="Popup" Property="PopupAnimation" Value="None"/>
            </Trigger>
            <Trigger Property="IsHighlighted" Value="true">
                <Setter TargetName="Border" Property="Background" Value="DimGray"/>
                <Setter TargetName="Border" Property="BorderBrush" Value="Transparent"/>
            </Trigger>
            <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
                <Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="0,0,4,4"/>
                <Setter TargetName="SubmenuBorder" Property="Padding" Value="0,0,0,3"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Foreground" Value="LightSlateGray"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <ControlTemplate x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}" TargetType="MenuItem">
        <Border Name="Border" >
            <Grid>
                <ContentPresenter Margin="6,3,6,3" 
                                  ContentSource="Header"
                                  RecognizesAccessKey="True" />
            </Grid>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsHighlighted" Value="true">
                <Setter TargetName="Border" Property="Background" Value="DimGray"/>
                <Setter TargetName="Border" Property="BorderBrush" Value="Transparent"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Foreground" Value="LightSlateGray"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <ControlTemplate x:Key="{x:Static MenuItem.SubmenuItemTemplateKey}" TargetType="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="#FF2D2D30"
                        BorderThickness="1"
                        BorderBrush="#FF2D2D30">
                    <Path Name="CheckMark"
                          Width="7" Height="7" 
                          Visibility="Hidden" 
                          SnapsToDevicePixels="False" 
                          Stroke="DodgerBlue"
                          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="DimGray"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="LightSlateGray"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}"  TargetType="MenuItem">
        <Border Name="Border" >
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="13" 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="DodgerBlue" />
                <Popup Name="Popup"
                       Placement="Right"
                       HorizontalOffset="-4" 
                       IsOpen="{TemplateBinding IsSubmenuOpen}"
                       AllowsTransparency="True" 
                       Focusable="False"
                       PopupAnimation="Fade">
                    <Border Name="SubmenuBorder"
                            SnapsToDevicePixels="True"
                            Background="#FF2D2D30"
                            BorderBrush="#FF2D2D30"
                            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="DimGray"/>
            </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="LightSlateGray"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <Style x:Key="MenuItemStyle" TargetType="MenuItem">
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Style.Triggers>
            <Trigger Property="Role" Value="TopLevelHeader">
                <Setter Property="Template" Value="{StaticResource {x:Static MenuItem.TopLevelHeaderTemplateKey}}"/>
                <Setter Property="Grid.IsSharedSizeScope" Value="true"/>
            </Trigger>
            <Trigger Property="Role" Value="TopLevelItem">
                <Setter Property="Template" Value="{StaticResource {x:Static MenuItem.TopLevelItemTemplateKey}}"/>
            </Trigger>
            <Trigger Property="Role" Value="SubmenuHeader">
                <Setter Property="Template" Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/>
            </Trigger>
            <Trigger Property="Role" Value="SubmenuItem">
                <Setter Property="Template" Value="{StaticResource {x:Static MenuItem.SubmenuItemTemplateKey}}"/>
            </Trigger>
        </Style.Triggers>
    </Style>

【讨论】:

  • 这并不能解决我的问题,您的样式不涵盖鼠标悬停事件,所以我仍然看到鼠标悬停时的二次突出显示。
  • 但是你的第二个例子更接近,给予或采取一些额外的造型。
【解决方案2】:

我遇到了同样的问题,并使用仅包含标签的自定义 MenuItem 模板解决了它:

<ContextMenu ItemsSource="{Binding ReportLayouts}" x:Name="CtxReportsMenu">
   <ContextMenu.ItemTemplate>
       <DataTemplate>
          <MenuItem Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=DataContext.ReportCmd}"
                    CommandParameter="{Binding }">
             <MenuItem.Template>
                <ControlTemplate>
                   <Label Content="{Binding Report_Description}"/>
                </ControlTemplate>
             </MenuItem.Template>
           </MenuItem>
       </DataTemplate>
   </ContextMenu.ItemTemplate>

【讨论】:

    【解决方案3】:

    只需从默认 MenuItem 模板中删除 Property="IsHighlighted" 触发器即可:

    <ControlTemplate TargetType="{x:Type MenuItem}">
        <Grid SnapsToDevicePixels="True">
            <Rectangle x:Name="Bg" Fill="{TemplateBinding Background}" RadiusY="2" RadiusX="2" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="1"/>
            <Rectangle x:Name="InnerBorder" Margin="1" RadiusY="2" RadiusX="2"/>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition MinWidth="24" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
                    <ColumnDefinition Width="4"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="37"/>
                    <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
                    <ColumnDefinition Width="17"/>
                </Grid.ColumnDefinitions>
                <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" Margin="1" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
                <Border x:Name="GlyphPanel" BorderBrush="#FFCDD3E6" BorderThickness="1" Background="#FFE6EFF4" CornerRadius="3" Height="22" Margin="1" Visibility="Hidden" Width="22">
                    <Path x:Name="Glyph" Data="M0,5.1L1.7,5.2 3.4,7.1 8,0.4 9.2,0 3.3,10.8z" Fill="#FF0C12A1" FlowDirection="LeftToRight" Height="11" Width="9"/>
                </Border>
                <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                <TextBlock Grid.Column="4" Margin="{TemplateBinding Padding}" Text="{TemplateBinding InputGestureText}"/>
            </Grid>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="Icon" Value="{x:Null}">
                <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
            </Trigger>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
                <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
            </Trigger>
            <Trigger Property="IsHighlighted" Value="True">
                <Setter Property="Fill" TargetName="Bg">
                    <Setter.Value>
                        <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                            <GradientStop Color="#34C5EBFF" Offset="0"/>
                            <GradientStop Color="#3481D8FF" Offset="1"/>
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
                <Setter Property="Stroke" TargetName="Bg" Value="#8071CBF1"/>
                <Setter Property="Stroke" TargetName="InnerBorder" Value="#40FFFFFF"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Foreground" Value="#FF9A9A9A"/>
                <Setter Property="Background" TargetName="GlyphPanel" Value="#FFEEE9E9"/>
                <Setter Property="BorderBrush" TargetName="GlyphPanel" Value="#FFDBD6D6"/>
                <Setter Property="Fill" TargetName="Glyph" Value="#FF848589"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

    【讨论】:

      【解决方案4】:

      这是一个很晚的答案,但也许它可以帮助某人。

      第二个亮点在那里,因为您实际上在原始菜单项中有一个额外的 MenuItem。

      这有点违反直觉,但是当您在 WPF 中绑定菜单的 ItemsSource 时,它​​会自动创建 MenuItems 而无需为其提供 DataTemplate。您提供的 DataTemplate 实际上是在最初创建的 MenuItem 中的 ContentPresenter 中进行的。

      所以你应该使用 ItemContainerStyle 来设置 MenuItem 的样式,而不是给它一个 DataTemplate。

      我现在没有机会尝试以下代码,但它应该可以解决问题:

      <Button.ContextMenu>
          <ContextMenu ItemsSource="{Binding SelectedTreeItem.MetaTargets}">
              <ContextMenu.ItemContainerStyle>
                  <Style TargetType="MenuItem">
                      <Style.Setters>
                          <Setter Property="Header" Value="{Binding Name}"/>
                          <Setter Property="Command" Value="{Binding Path=SelectedTreeItem.AddTargetCommandRelay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
                          <Setter Property="CommandParameter" Value="{Binding}"/>
                      </Style.Setters>
                  </Style>
              </ContextMenu.ItemContainerStyle>
          </ContextMenu>
      </Button.ContextMenu>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-08
        • 1970-01-01
        • 2015-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-01
        相关资源
        最近更新 更多