CommunityToolkit / dotnet

.NET Community Toolkit is a collection of helpers and APIs that work for all .NET developers and are agnostic of any specific UI platform. The toolkit is maintained and published by Microsoft, and part of the .NET Foundation.
https://docs.microsoft.com/dotnet/communitytoolkit/?WT.mc_id=dotnet-0000-bramin
Other
3.05k stars 300 forks source link

Executing RelayCommand throws System.MethodAccessException: Attempt by method #804

Closed Symbai closed 3 months ago

Symbai commented 11 months ago

Describe the bug

I'm trying to figure out how to use a simple command which canexecute depends on a bool property. Unfortunately the sample application is heavily outdated as there are like 3 different ways of how to setup a command. And all of them are missing the canexecute step.

This is the exception I receive:

Unhandled exception. System.MethodAccessException: Attempt by method 'CompiledAvaloniaXaml.XamlIlTrampolines.xxx:xxx.ViewModels.MainWindowViewModel+LoginCommand_0!CommandExecuteTrampoline(System.Object, System.Object)' to access method 'xxx.ViewModels.MainWindowViewModel.LoginCommand()' failed.
   at CompiledAvaloniaXaml.XamlIlTrampolines.xxxx:xxx.ViewModels.MainWindowViewModel+LoginCommand_0!CommandExecuteTrampoline(Object, Object)

Anyway please see code below. Any help is appreciated

Regression

No response

Steps to reproduce

.NET 7
Avalonia

#
[ObservableProperty]
bool isNotLoggingIn = true;

[RelayCommand(CanExecute = nameof(IsNotLoggingIn))]
private async Task LoginCommand()
{
    IsNotLoggingIn = false;
    await Task.Delay(5000);
    IsNotLoggingIn = true;
}

Expected behavior

When I press the button the button should get disabled and after 5 seconds get enabled. But pressing the button throws the exception above.

Screenshots

No response

IDE and version

VS 2022 Preview

IDE version

No response

Nuget packages

Nuget package version(s)

8.2.2

Additional context

No response

Help us help you

No, just wanted to report this

passion729 commented 3 months ago

Try to make the LoginCommand() method to public, it worked for me.

Sergio0694 commented 3 months ago
private async Task LoginCommand()

This is incorrect. You shouldn't have the "Command" suffix in your method, because the generator will already append it. You should also be getting a warning about this from the analyzer I think. You should rename that method to just Login and keep it private, and then bind to the generated LoginCommand.

If that doesn't work because the Avalonia source generators can't see the generated command when they run, that's not a bug in the MVVM Toolkit, but an expected limitations of concurrent source generators, and it's by design. If so, you might not be able to use a generated command here if Avalonia works that way.