[英]WPF: Two Columns in Context Menu Item
I am trying to create a context menu with two columns like this: 我正在尝试创建具有两列的上下文菜单,如下所示:
The text of the item is bound the Name property of the item and the shortcut key is bound to the GestureText property. 项目的文本绑定到项目的Name属性,快捷键绑定到GestureText属性。 However, the column definitions do not seem to be obeyed and I see this:
但是,似乎没有遵守列定义,我看到了这一点:
My XAML is as follows: 我的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# 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)
}
};
}
}
What's wrong here? 怎么了
You can bind InputGestureText
in ItemContainerStyle
to GestureText
: 您可以将
ItemContainerStyle
InputGestureText
绑定到GestureText
:
<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>
Also note that setting HorizontalAlighnment
or HorizontalContentAlignment
is not going to help. 另请注意,设置
HorizontalAlighnment
或HorizontalContentAlignment
不会有帮助。 Please note this part of the default style: 请注意默认样式的这一部分:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="Icon" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"
SharedSizeGroup="Shortcut" />
<ColumnDefinition Width="13" />
</Grid.ColumnDefinitions>
and the margin of the TextBlock in the third column which is Margin="5,2,2,2"
. 第三列中的TextBlock的边距为
Margin="5,2,2,2"
。
I haven't tested this, but my guess would be that the MenuItems that contain your columns are not taking up the full width themselves (they are probably left aligned). 我没有测试过,但是我猜想是包含您的列的MenuItems本身并没有占据整个宽度(它们可能保持对齐)。 So maybe try changing their alignment using , eg something like this:
因此,也许尝试使用来更改其对齐方式,例如:
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ContextMenu.ItemContainerStyle>
If you really want to create a custom looking ContextMenu
you need to override the ControlTemplate
of the MenuItem
ItemContainer, ie define your Grid
in the ControlTemplate
instead of this one instead of in the ItemTemplate
of the ContextMenu: 如果您确实想创建自定义外观的
ContextMenu
,则需要覆盖MenuItem
ItemContainer的ControlTemplate
,即在ControlTemplate
而不是在ContextMenu的ItemTemplate
中定义此Grid
:
<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>
If you simply want to bind the InputGestureText
property to your GestureText
property you should refer to @Ron's answer. 如果只想将
InputGestureText
属性绑定到GestureText
属性,则应参考GestureText
的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.