简体   繁体   中英

How to set the Horizontal Alignment of the Input Gesture Texts in Menus in WPF?

I'm making an application with WPF and have a Menu . In that menu, most of the items have keyboard shortcuts, or input gestures. How do I set the horizontal alignment of the text that displays the input gesture?

What I want:

目标:输入手势向右对齐的菜单项。

How it looks:

实际:输入手势左对齐的菜单项。

I have already looked this problem up, but I seem to be the only person who cares about this.

In order to change the horizontal alignment of the input gesture text, you have to adapt the control template of MenuItem . You can either create it from scratch or create a copy of the default style using Blend or Visual Studio . I recommend the latter. If you want to now more about the required parts and visual states of the MenuItem control, you can refer to the documentation .

In the following, I extracted the default style and only the control template and resources that are actually needed to change the input gesture text alignment. The essential change is in the menuGestureText TextBlock .

<TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center" HorizontalAlignment="Right"/>

As you can see, I set the HorizontalAlignment to Right . Here is the essential XAML markup needed:

<SolidColorBrush x:Key="Menu.Static.Background" Color="#FFF0F0F0"/>
<SolidColorBrush x:Key="Menu.Static.Border" Color="#FF999999"/>
<SolidColorBrush x:Key="Menu.Static.Foreground" Color="#FF212121"/>
<SolidColorBrush x:Key="Menu.Disabled.Foreground" Color="#FF707070"/>
<SolidColorBrush x:Key="MenuItem.Selected.Background" Color="#3D26A0DA"/>
<SolidColorBrush x:Key="MenuItem.Selected.Border" Color="#FF26A0DA"/>
<SolidColorBrush x:Key="MenuItem.Highlight.Background" Color="#3D26A0DA"/>
<SolidColorBrush x:Key="MenuItem.Highlight.Border" Color="#FF26A0DA"/>
<SolidColorBrush x:Key="MenuItem.Highlight.Disabled.Background" Color="#0A000000"/>
<SolidColorBrush x:Key="MenuItem.Highlight.Disabled.Border" Color="#21000000"/>

<Geometry x:Key="Checkmark">F1 M 10.0,1.2 L 4.7,9.1 L 4.5,9.1 L 0,5.2 L 1.3,3.5 L 4.3,6.1L 8.3,0 L 10.0,1.2 Z</Geometry>

<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
   <Border x:Name="templateRoot" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Height="22" SnapsToDevicePixels="true">
      <Grid Margin="-1">
         <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
            <ColumnDefinition Width="13"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
            <ColumnDefinition Width="20"/>
         </Grid.ColumnDefinitions>
         <ContentPresenter x:Name="Icon" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
         <Border x:Name="GlyphPanel" Background="{StaticResource MenuItem.Selected.Background}" BorderThickness="1" BorderBrush="{StaticResource MenuItem.Selected.Border}" ClipToBounds="False" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" VerticalAlignment="Center" Visibility="Hidden" Width="22">
            <Path x:Name="Glyph" Data="{StaticResource Checkmark}" FlowDirection="LeftToRight" Fill="{StaticResource Menu.Static.Foreground}" Height="11" Width="10"/>
         </Border>
         <ContentPresenter x:Name="menuHeaderContainer" ContentSource="Header" Grid.Column="2" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
         <TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center" HorizontalAlignment="Right"/>
      </Grid>
   </Border>
   <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="Background" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Background}"/>
         <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Border}"/>
      </Trigger>
      <Trigger Property="IsEnabled" Value="False">
         <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{StaticResource Menu.Disabled.Foreground}"/>
         <Setter Property="Fill" TargetName="Glyph" Value="{StaticResource Menu.Disabled.Foreground}"/>
      </Trigger>
      <MultiTrigger>
         <MultiTrigger.Conditions>
            <Condition Property="IsHighlighted" Value="True"/>
            <Condition Property="IsEnabled" Value="False"/>
         </MultiTrigger.Conditions>
         <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Disabled.Background}"/>
         <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Disabled.Border}"/>
      </MultiTrigger>
   </ControlTemplate.Triggers>
</ControlTemplate>

<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
   <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
   <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
   <Setter Property="Background" Value="Transparent"/>
   <Setter Property="BorderBrush" Value="Transparent"/>
   <Setter Property="BorderThickness" Value="1"/>
   <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
   <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
   <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
   <Style.Triggers>
      <Trigger Property="Role" Value="TopLevelHeader">
         <Setter Property="Background" Value="Transparent"/>
         <Setter Property="BorderBrush" Value="Transparent"/>
         <Setter Property="Foreground" Value="{StaticResource Menu.Static.Foreground}"/>
         <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
         <Setter Property="Padding" Value="6,0"/>
      </Trigger>
      <Trigger Property="Role" Value="TopLevelItem">
         <Setter Property="Background" Value="{StaticResource Menu.Static.Background}"/>
         <Setter Property="BorderBrush" Value="{StaticResource Menu.Static.Border}"/>
         <Setter Property="Foreground" Value="{StaticResource Menu.Static.Foreground}"/>
         <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
         <Setter Property="Padding" Value="6,0"/>
      </Trigger>
      <Trigger Property="Role" Value="SubmenuHeader">
         <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
      </Trigger>
   </Style.Triggers>
</Style>

You can use the style by referencing it as ItemContainerStyle in Menu or assign the style to MenuItem s.

<Menu ItemContainerStyle="{StaticResource MenuItemStyle}">
   <MenuItem Header="File">
      <MenuItem Header="New file" InputGestureText="Ctrl+N"/>
      <MenuItem Header="New template" InputGestureText="Ctrl+Shift+N"/>
   </MenuItem>
</Menu>

Another option is to create an implicit style that is applied automatically to all MenuItem s in scope.

<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MenuItemStyle}"/>

This is the result, the input gesture text is aligned to the right.

输入手势文本向右对齐的菜单。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM