Can't use ICommand attribute in view model using CommunityToolkit.Mvvm
Asked Answered
C

4

17

In my view models, I wanted to use the source generators in CommunityToolkit.Mvvm but for some reason I can't seem to use [ICommand] attribute with my action methods.

The error I get is:

Cannot apply attribute class 'ICommand' because it is abstract

Here's the base class for my view model model.

using CommunityToolkit.Mvvm.ComponentModel;

namespace MyApp.ViewModels
{
    public partial class BaseViewModel : ObservableObject
    {
        [ObservableProperty]
        bool isBusy = false;

        [ObservableProperty]
        string title = string.Empty;
    }
}

And here's my view model class:

public class MyViewModel : BaseViewModel
{
   [ObservableProperty]
   string firstName;

   [ObservableProperty]
   string lastName;

   [ICommand] // <-- This is where I get the error I mentioned above
   async Task DoSomething()
   {
       // Do something here...
   }
}
Canonist answered 10/6, 2022 at 17:38 Comment(3)
Hey Sam, I'll try to reproduce this when I have some free time.Koziel
Perhaps you're accidentally using the ICommand interface from System.Windows.Input, instead of the ICommandAttribute from the CommunityTookit. Try to replace [ICommand] with [CommunityToolkit.Mvvm.Input.ICommand] and see if that was the case.Chigoe
I was sure you were right because I am using System.Windows.Input but I don't find ICommand in CommunityToolkit.Mvvm.Input.ICommand. I'm using version 8.0.0-preview4. The only thing I see in there is RelayCommand but that I can't seem to use it as an attribute and it doesn't work in the above example.Canonist
T
30

EDIT

Yes, they've renamed the ICommandAttribute to RelayCommandAttribute. It's metioned in the breaking changes section of the 8.0.0-preview4 release notes.

Original answer

The problem seems to be what @Luca Clavarino mentioned in the comments:

Perhaps you're accidentally using the ICommand interface from System.Windows.Input,instead of the ICommandAttribute from the CommunityTookit. Try to replace [ICommand] with [CommunityToolkit.Mvvm.Input.ICommand] and see if that was the case.

And I think I know why this might be happening to you. The ICommandAttribute seems to be missing in CommunityToolkit.Mvvm 8.0.0-preview4 so intellisense won't offer the using CommunityToolkit.Mvvm.Input statement and instead offers using System.Windows.Input;.

The problem can be resolved by downgrading to CommunityToolkit.Mvvm 8.0.0-preview3, that version works fine for me.

Here's a working sample (using CommunityToolkit.Mvvm 8.0.0-preview3).

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MyApp.ViewModels
{
    public partial class BaseViewModel : ObservableObject
    {
        [ObservableProperty]
        bool isBusy = false;

        [ObservableProperty]
        string title = string.Empty;
    }

    public partial class MyViewModel : BaseViewModel
    {
        [ObservableProperty]
        string firstName;

        [ObservableProperty]
        string lastName;

        [ICommand] //works in 8.0.0-preview3
        async Task DoSomething()
        {
            // Do something here...
        }
    }
}

I've also noticed that while the ICommandAttribute is gone in 8.0.0-preview4, there's a RelayCommandAttribute instead. Maybe they've simply renamed it.

Using the RelayCommandAttribute instead of ICommandAttribute in 8.0.0-preview4 seems to be working.

[RelayCommand] //works in 8.0.0-preview4
async Task DoSomething()
{
    // Do something here...
}
Trabeated answered 13/6, 2022 at 4:28 Comment(2)
Thank you! As you said, [ICommand] is now [RelayCommand] and another important point is that if we name the method DoSomething(), the generated command will be DoSomethingCommand(). This is the reason why I couldn't get [RelayCommand] to work before. Once I referenced the method with Command suffix, it worked fine. Thanks again for your help!Canonist
Excellent, this is the only helpful thread that answers a search of "relaycommand is not an attribute class".Tallage
U
18

The accepted answer has a lot of text just to say in 8.0.0 Preview 4 the [ICommand] attribute was renamed to [RelayCommand]. It is listed in the breaking changes of the release notes.

Unstained answered 19/10, 2022 at 10:52 Comment(1)
I figured as much. Thanks!Workhorse
C
1

If you download the current version of CommunityTookkit.Mvvm 8.2.2 above it actually [RelayCommand] this will work hope this helps

Crossbill answered 27/12, 2023 at 20:52 Comment(0)
A
0

Works with 8.0.0-preview3 not 8.0.0-preview4 or latest release 8.0.0.

Agincourt answered 6/10, 2022 at 12:54 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Wina

© 2022 - 2024 — McMap. All rights reserved.