2017-03-04 130 views
0

我想创建具有两列的上下文菜单是这样的:WPF:在上下文菜单项两列

Context Menu

项目的文本约束的项目和快捷方式的名称属性键被绑定到GestureText属性。然而,似乎在列定义不被遵守,我看到:enter image description here

我的XAML如下:

<Window x:Class="ContextMenu2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid Margin="0,2,0.4,-2.2"> 
     <TextBlock Text="RightClickMe" HorizontalAlignment="Left" VerticalAlignment="Top"> 
      <TextBlock.ContextMenu> 
       <ContextMenu ItemsSource="{Binding Items}"> 
        <ContextMenu.ItemTemplate> 
         <DataTemplate> 
          <Grid> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="50*"/> 
            <ColumnDefinition Width="70*"/> 
           </Grid.ColumnDefinitions> 
           <TextBlock Grid.Column="0" Text="{Binding Name}" /> 
           <TextBlock Grid.Column="1" Text="{Binding GestureText}"/> 
          </Grid> 
         </DataTemplate> 
        </ContextMenu.ItemTemplate> 
       </ContextMenu> 
      </TextBlock.ContextMenu> 
     </TextBlock> 
    </Grid> 
</Window> 

C#

using System; 
using System.Collections.ObjectModel; 
using System.Globalization; 
using System.Windows; 
using System.Windows.Input; 

namespace ContextMenu2 
{ 
    public class CMenu 
    { 
     public String Name { get; set; } 
     public string GestureText { get; set; } 
    } 

    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = this; 
     } 

     public ObservableCollection<CMenu> Items { get; set; }= new ObservableCollection<CMenu> 
     { 
      new CMenu() 
      { 
       Name = "Press me", 
       GestureText = 
        new KeyGesture(Key.Q, ModifierKeys.Control).GetDisplayStringForCulture(CultureInfo.CurrentUICulture) 
      }, 
      new CMenu() 
      { 
       Name = "Press me too", 
       GestureText = 
        new KeyGesture(Key.R, ModifierKeys.Control).GetDisplayStringForCulture(CultureInfo.CurrentUICulture) 
      } 
     }; 
    } 
} 

有什么不对吗?

回答

0

我还没有测试过这个,但是我的猜测是包含你的列的MenuItems没有占用全部宽度(它们可能左对齐)。因此,可以尝试使用例如是这样的:

<ContextMenu.ItemContainerStyle> 
    <Style TargetType="{x:Type MenuItem}"> 
     <Setter Property="HorizontalAlignment" Value="Stretch"/> 
    </Style> 
</ContextMenu.ItemContainerStyle> 
1

可以在ItemContainerStyle结合InputGestureTextGestureText

<ContextMenu ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch"> 
    <ContextMenu.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Name}" /> 
     </DataTemplate> 
    </ContextMenu.ItemTemplate> 
    <ContextMenu.ItemContainerStyle> 
     <Style TargetType="MenuItem"> 
      <Setter Property="InputGestureText" Value="{Binding GestureText}"/> 
     </Style> 
    </ContextMenu.ItemContainerStyle> 
</ContextMenu> 

另外请注意,设置HorizontalAlighnmentHorizontalContentAlignment是不会帮助。请注意的default style:

<Grid.ColumnDefinitions> 
    <ColumnDefinition Width="Auto" 
         SharedSizeGroup="Icon" /> 
    <ColumnDefinition Width="*" /> 
    <ColumnDefinition Width="Auto" 
         SharedSizeGroup="Shortcut" /> 
    <ColumnDefinition Width="13" /> 
</Grid.ColumnDefinitions> 

这部分和第三列是Margin="5,2,2,2" TextBlock的保证金。

0

如果你真的想创建一个自定义看ContextMenu,你需要重写MenuItem ItemContainer的ControlTemplate,即定义GridControlTemplate,而不是这一个,而不是在文本菜单的ItemTemplate

<TextBlock Text="RightClickMe" HorizontalAlignment="Left" VerticalAlignment="Top"> 
    <TextBlock.ContextMenu> 
     <ContextMenu ItemsSource="{Binding Items}"> 
      <ContextMenu.ItemContainerStyle> 
       <Style TargetType="MenuItem"> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="{x:Type MenuItem}"> 
           <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> 
            <Grid Margin="-1"> 
             <Grid.ColumnDefinitions> 
              <ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/> 
              <ColumnDefinition Width="13"/> 
              <ColumnDefinition Width="*"/> 
              <ColumnDefinition Width="5*" SharedSizeGroup="a"/> 
              <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/> 
              <ColumnDefinition Width="7*" SharedSizeGroup="b"/> 
             </Grid.ColumnDefinitions> 
             <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/> 
             <Border x:Name="GlyphPanel" BorderBrush="#FF26A0DA" BorderThickness="1" Background="#3D26A0DA" ClipToBounds="False" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22"> 
              <Path x:Name="Glyph" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="#FF212121" FlowDirection="LeftToRight" Height="11" Width="10"/> 
             </Border> 
             <ContentPresenter x:Name="menuHeaderContainer" ContentTemplate="{TemplateBinding HeaderTemplate}" 
                     Content="{Binding Name}" Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/> 
             <TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" 
                   Text="{Binding GestureText}" 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="#3D26A0DA"/> 
             <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/> 
            </Trigger> 
            <Trigger Property="IsEnabled" Value="False"> 
             <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/> 
             <Setter Property="Fill" TargetName="Glyph" Value="#FF707070"/> 
            </Trigger> 
            <MultiTrigger> 
             <MultiTrigger.Conditions> 
              <Condition Property="IsHighlighted" Value="True"/> 
              <Condition Property="IsEnabled" Value="False"/> 
             </MultiTrigger.Conditions> 
             <Setter Property="Background" TargetName="templateRoot" Value="#0A000000"/> 
             <Setter Property="BorderBrush" TargetName="templateRoot" Value="#21000000"/> 
            </MultiTrigger> 
           </ControlTemplate.Triggers> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </ContextMenu.ItemContainerStyle> 
     </ContextMenu> 
    </TextBlock.ContextMenu> 
</TextBlock> 

如果你只是想将InputGestureText属性绑定到你的GestureText属性,你应该参考@ Ron的答案。