Browse Source

Add MenuItem.InputGestureText.

pull/3602/head
Steven Kirk 7 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.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.VisualTree;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -48,6 +49,12 @@ namespace Avalonia.Controls
public static readonly StyledProperty<object> IconProperty = public static readonly StyledProperty<object> IconProperty =
AvaloniaProperty.Register<MenuItem, object>(nameof(Icon)); 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> /// <summary>
/// Defines the <see cref="IsSelected"/> property. /// Defines the <see cref="IsSelected"/> property.
/// </summary> /// </summary>
@ -93,6 +100,7 @@ namespace Avalonia.Controls
private ICommand _command; private ICommand _command;
private bool _commandCanExecute = true; private bool _commandCanExecute = true;
private Popup _popup; private Popup _popup;
private IDisposable _gridHack;
/// <summary> /// <summary>
/// Initializes static members of the <see cref="MenuItem"/> class. /// Initializes static members of the <see cref="MenuItem"/> class.
@ -194,6 +202,19 @@ namespace Avalonia.Controls
set { SetValue(IconProperty, value); } 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> /// <summary>
/// Gets or sets a value indicating whether the <see cref="MenuItem"/> is currently selected. /// Gets or sets a value indicating whether the <see cref="MenuItem"/> is currently selected.
/// </summary> /// </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> /// <summary>
/// Called when the <see cref="MenuItem"/> is clicked. /// Called when the <see cref="MenuItem"/> is clicked.
/// </summary> /// </summary>

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

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

Loading…
Cancel
Save