Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Dynamically-created menu items with commands do not work #15858

Closed
LeftofZen opened this issue May 30, 2024 · 4 comments
Closed

Dynamically-created menu items with commands do not work #15858

LeftofZen opened this issue May 30, 2024 · 4 comments
Labels

Comments

@LeftofZen
Copy link

LeftofZen commented May 30, 2024

Describe the bug

A MenuItem with an ItemsSource specified, and which gets its Command from a property on an item in that collection, does not work. "Not work" meaning, the MenuItem is disabled regardless of what other settings you apply to the MenuItem in axaml or code.

Code example below is written with .NET 8, Avalonia 11.0.10, with the Avalonia MVVM template with ReactiveUI extensions.

To Reproduce

Easiest just to post the working SSCCE so everyone can recreate. App.axaml/cs and all other files are unchanged from the generated template, only these 2 files are changed:

For MainWindowViewModel.cs

using ReactiveUI;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Input;

namespace MenuItemCommandBug.ViewModels
{
	public record MenuItemModel(string Name, ICommand MenuCommand);

	public class MainWindowViewModel : ViewModelBase
	{
		public List<MenuItemModel> Items { get; init; }

		public MainWindowViewModel()
			=> Items =
			[
				new("Item1", ReactiveCommand.Create(() => Debug.WriteLine("Item1"))),
				new("Item2", ReactiveCommand.Create(() => Debug.WriteLine("Item2"))),
				new("Item3", ReactiveCommand.Create(() => Debug.WriteLine("Item3"))),
			];
	}
}

and for MainWindow.axaml

<Window xmlns="https://github.com/avaloniaui"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:vm="using:MenuItemCommandBug.ViewModels"
		xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
		xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
		mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
		x:Class="MenuItemCommandBug.Views.MainWindow"
		x:DataType="vm:MainWindowViewModel"
		Icon="/Assets/avalonia-logo.ico"
Title="MenuItemCommandBug">

	<Menu>
		<MenuItem Header="Items" ItemsSource="{Binding Items}" >
			<MenuItem.ItemTemplate>
				<DataTemplate>
					<MenuItem Header="{Binding Name}" Command="{Binding MenuCommand}" IsEnabled="True" Focusable="True"/>
				</DataTemplate>
			</MenuItem.ItemTemplate>
		</MenuItem>
	</Menu>
</Window>

Expected behavior

I would expect the menu items are not disabled and that when clicked, they execute their bound command.

Avalonia version

11.0.10

OS

Windows

Additional context

I note #3100 is the 'same' issue, but that applies to an older Avalonia version and unfortunately that workaround does not work/is not applicable in Avalonia 11. It seems that buggy behaviour was carried over to Avalonia 11 though.

Things I have tried that have no effect, ie the bug still exists:

  • Using .NET 6 (code example above is written in .NET 8)
  • Using a class instead of a record for MenuItemModel
  • Using ReactiveCommand<Unit, Unit> instead of ICommand for MenuCommand
  • Using ObservableCollection (or any other collection) instead of List for Items
  • Using [Reactive] tags on any/all the properties in both classes
  • Using set; instead of init;
  • Using parameters (ie the bug still exists with your command contains parameters and you set CommandParameter in the axaml)

What "works" is removing the bound command from the axaml, ie removing Command="{Binding MenuCommand}" makes the menu item enabled again - but obviously this makes the menu item useless as clicking it does nothing.

Binding/command also works when the command is a property of the MainWindowViewModel, though this isn't a solution when the commands are dynamically generated.

@LeftofZen LeftofZen added the bug label May 30, 2024
@rabbitism
Copy link
Contributor

The solution in #3100 still works, but your datatemplate content should not be menuitem. Otherwise your will have a menuitem inside menuitem.

@LeftofZen
Copy link
Author

LeftofZen commented May 30, 2024

Thankyou for the reply, but as I already mentioned, the solution in #3100 does not work. Please try it out yourself and see. Here is the full axaml code for it so you can verify yourself that it truly does not work:

<Window xmlns="https://github.com/avaloniaui"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:vm="using:MenuItemCommandBug.ViewModels"
		xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
		xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
		mc:Ignorable="d" d:DesignWidth="256" d:DesignHeight="128"
		x:Class="MenuItemCommandBug.Views.MainWindow"
		x:DataType="vm:MainWindowViewModel"
		Icon="/Assets/avalonia-logo.ico"
Title="MenuItemCommandBug">

	<Menu>
		<MenuItem Header="Items" ItemsSource="{Binding Items}">
			<MenuItem.ItemTemplate>
				<DataTemplate>
					<MenuItem Header="{Binding Name}" Command="{Binding MenuCommand}" IsEnabled="True" Focusable="True"/>
				</DataTemplate>
			</MenuItem.ItemTemplate>
			<MenuItem.Styles>
				<Style Selector="MenuItem.SubItems MenuItem" x:DataType="vm:MenuItemModel">
					<Setter Property="Header" Value="{Binding Name}"/>
					<Setter Property="Command" Value="{Binding MenuCommand}"/>
				</Style>
			</MenuItem.Styles>
		</MenuItem>
	</Menu>
</Window>

On your other point:

but your datatemplate content should not be menuitem. Otherwise your will have a menuitem inside menuitem.

Notice ItemsSource="{Binding Items}" - this is how you make nested menu items. If you are confused about what this looks like visually, see this screenshot; these sub-menu items are not enabled when they should be.

image

The last thing you can do to convince yourself this is truly a bug is to remove the Command="{Binding MenuCommand}" from the axaml. The (sub) menu items are re-enabled again. This shows there is a bug in the interaction of menu items and commands.

@rabbitism
Copy link
Contributor

rabbitism commented May 30, 2024

I tried and replied. You didnt set Classes for your Parent MenuItem, thats why it does not work for you.
Classes="SubItems"

@LeftofZen
Copy link
Author

LeftofZen commented May 30, 2024

Apologies, this does appear to work. The reason I didn't include Classes is because Intellisense did not like it and wouldn't autocomplete, and there were also issues with Items -> ItemsSource, but pasting it in does work. Thanks for the help!

@AvaloniaUI AvaloniaUI locked and limited conversation to collaborators May 30, 2024
@maxkatz6 maxkatz6 converted this issue into discussion #15860 May 30, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Projects
None yet
Development

No branches or pull requests

2 participants