Browse Source

Add MenuItem.InputGestureText.

pull/3602/head
Steven Kirk 6 years ago
parent
commit
8a0ccea273
  1. 51
      src/Avalonia.Controls/MenuItem.cs
  2. 26
      src/Avalonia.Themes.Default/MenuItem.xaml

51
src/Avalonia.Controls/MenuItem.cs

@ -13,6 +13,7 @@ using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
namespace Avalonia.Controls
{
@ -48,6 +49,12 @@ namespace Avalonia.Controls
public static readonly StyledProperty<object> IconProperty =
AvaloniaProperty.Register<MenuItem, object>(nameof(Icon));
/// <summary>
/// Defines the <see cref="InputGestureText"/> property.
/// </summary>
public static readonly StyledProperty<string> InputGestureTextProperty =
AvaloniaProperty.Register<MenuItem, string>(nameof(InputGestureText));
/// <summary>
/// Defines the <see cref="IsSelected"/> property.
/// </summary>
@ -93,6 +100,7 @@ namespace Avalonia.Controls
private ICommand _command;
private bool _commandCanExecute = true;
private Popup _popup;
private IDisposable _gridHack;
/// <summary>
/// Initializes static members of the <see cref="MenuItem"/> class.
@ -194,6 +202,19 @@ namespace Avalonia.Controls
set { SetValue(IconProperty, value); }
}
/// <summary>
/// Gets or sets the input gesture that will be displayed in the menu item.
/// </summary>
/// <remarks>
/// Setting this property does not cause the input gesture to be handled by the menu item,
/// it simply displays the gesture text in the menu.
/// </remarks>
public object InputGestureText
{
get { return GetValue(InputGestureTextProperty); }
set { SetValue(InputGestureTextProperty, value); }
}
/// <summary>
/// Gets or sets a value indicating whether the <see cref="MenuItem"/> is currently selected.
/// </summary>
@ -306,6 +327,36 @@ namespace Avalonia.Controls
}
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
if (this.GetVisualParent() is IControl parent)
{
// HACK: This nasty but it's all WPF's fault. Grid uses an inherited attached
// property to store SharedSizeGroup state, except property inheritance is done
// down the logical tree. In this case, the control which is setting
// Grid.IsSharedSizeScope="True" is not in the logical tree. Instead of fixing
// the way Grid stores shared size state, the developers of WPF just created a
// binding of the internal state of the visual parent to the menu item. We don't
// have much choice but to do the same for now unless we want to refactor Grid,
// which I honestly am not brave enough to do right now. Here's the same hack in
// the WPF codebase:
//
// https://github.com/dotnet/wpf/blob/89537909bdf36bc918e88b37751add46a8980bb0/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/MenuItem.cs#L2126-L2141
_gridHack = Bind(
DefinitionBase.PrivateSharedSizeScopeProperty,
parent.GetBindingObservable(DefinitionBase.PrivateSharedSizeScopeProperty));
}
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);
_gridHack.Dispose();
_gridHack = null;
}
/// <summary>
/// Called when the <see cref="MenuItem"/> is clicked.
/// </summary>

26
src/Avalonia.Themes.Default/MenuItem.xaml

@ -11,7 +11,14 @@
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid ColumnDefinitions="20,5,*,20">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGT"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter Name="icon"
Content="{TemplateBinding Icon}"
Width="16"
@ -36,12 +43,15 @@
</DataTemplate>
</ContentPresenter.DataTemplates>
</ContentPresenter>
<TextBlock Grid.Column="3"
Text="{TemplateBinding InputGestureText}"
VerticalAlignment="Center"/>
<Path Name="rightArrow"
Data="M0,0L4,3.5 0,7z"
Fill="{DynamicResource ThemeForegroundBrush}"
Margin="10,0,0,0"
VerticalAlignment="Center"
Grid.Column="3"/>
Grid.Column="4"/>
<Popup Name="PART_Popup"
PlacementMode="Right"
StaysOpen="True"
@ -55,7 +65,8 @@
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemTemplate="{TemplateBinding ItemTemplate}"
Margin="4 2"/>
Margin="4 2"
Grid.IsSharedSizeScope="True"/>
</ScrollViewer>
</Border>
</Popup>
@ -102,10 +113,11 @@
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer>
<ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemTemplate="{TemplateBinding ItemTemplate}"
Margin="2"/>
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemTemplate="{TemplateBinding ItemTemplate}"
Margin="2"
Grid.IsSharedSizeScope="True"/>
</ScrollViewer>
</Border>
</Popup>

Loading…
Cancel
Save