Sam
Sam

Reputation: 30334

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

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...
   }
}

Upvotes: 18

Views: 11582

Answers (4)

Michal Diviš
Michal Diviš

Reputation: 2206

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...
}

Upvotes: 33

Waheed Rafiq
Waheed Rafiq

Reputation: 482

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

Upvotes: 1

IKavanagh
IKavanagh

Reputation: 6187

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.

Upvotes: 18

Shades49
Shades49

Reputation: 101

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

Upvotes: 0

Related Questions