Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Menu Item InputGesture does not display when using MVVM #16302

Closed
cornerbowlsoftware opened this issue Jul 12, 2024 · 1 comment
Closed

Menu Item InputGesture does not display when using MVVM #16302

cornerbowlsoftware opened this issue Jul 12, 2024 · 1 comment
Labels

Comments

@cornerbowlsoftware
Copy link

cornerbowlsoftware commented Jul 12, 2024

Describe the bug

Most samples I see used hard coded axaml to generate menu items. This breaks the MVVM architecture, so first, I'm surprised to see the Avalonia documentation show menu item implementation in this manner. Second, when binding to an 'InputGesture' the value is not displayed. This bug likely would have been caught if the docs used MVVM instead of showing hard coded values.

To Reproduce

Create a ViewModel to house the data model:

    public class MenuItemViewmModel : BaseViewModel
    {
        public string? Text { get; set; }
        public ICommand? Command { get; set; }
        public string? Icon { get; set; }
        public string? InputGestureText { get; set; }

        protected MenuItemViewModel()
        {
        }

        public MenuItemViewModel(string text)
        {
            Text = text;
        }

        public MenuItemViewModel(string text, string? icon)
        : this(text)
        {
            Icon = icon;
        }

        public MenuItemViewModel(string text, string? icon, ICommand? command)
        : this(text, icon)
        {
            Command = command;
        }

        public MenuItemViewModel(string text, string? icon, ICommand? command, string inputGestureText)
            : this(text, icon, command)
        {
            InputGestureText = inputGestureText;
        }

        public override string? ToString() => Text;

        public static object? Children => null;
    }

Create a style to bind the various context menu items to a view model:

	<Style Selector="MenuItem" x:DataType="lib:MenuItemViewModel">
		<Setter Property="Header" Value="{Binding Text}"/>
		<Setter Property="Command" Value="{Binding Command}"/>
		<Setter Property="InputGesture" Value="{Binding InputGestureText}"/>		
	</Style>

Next, define a context menu:

<local:BaseDataGrid
    x:Class="ServerManagerAvaloniaApp.FlatDataGrid"
    xmlns="https://github.com/avaloniaui"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:ServerManagerAvaloniaApp"
	xmlns:lib="using:ServerManagerLibrary"
    mc:Ignorable="d"
    d:DesignHeight="200" d:DesignWidth="400"
	x:DataType="lib:BaseViewModel">

	<DataGrid.ContextMenu>
		<ContextMenu ItemsSource="{Binding MenuItemVMs}"/>
	</DataGrid.ContextMenu>

</local:BaseDataGrid>

Run the app and display your control that hosts the menu items. Right click on the control. Notice the hot key, in this case "Ctrl+C" is not displayed. Put a breakpoint in the view model on InputGestureText. Reopen the view to regenerate the requests. Verify "Ctrl+C" is returned. Stop the program then change the style to hard code the InputGesture to "Ctrl+C" like so:

<Style Selector="MenuItem" x:DataType="lib:MenuItemModel">
	<Setter Property="Header" Value="{Binding Text}"/>
	<Setter Property="Command" Value="{Binding Command}"/>
	<Setter Property="InputGesture" Value="Ctrl+C"/>
</Style>

Rerun the application. Notice the InputGesture is displayed.

Expected behavior

The gesture should display.

Avalonia version

11.0.11

OS

Windows

Additional context

No response

@cornerbowlsoftware
Copy link
Author

I was able to get this working by adding my own string to key gesture converter:

	<Style Selector="MenuItem" x:DataType="lib:MenuItemModel">
		<Setter Property="Header" Value="{Binding Text}"/>
		<Setter Property="Command" Value="{Binding Command}"/>
		<Setter Property="InputGesture" Value="{Binding InputGestureText, Converter={StaticResource StringToKeyGestureConverter}}"/>
	</Style>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant