CommunityToolkit / CommunityToolkit/dotnet

Check if `CanExecute` in `RelayCommand.Execute`

Open
#748 0 comments 0 reactions 0 assignees View on GitHub
feature request :mailbox_with_mail:
Dominant language
C#
Stars
3.8k
Forks
400
PR merge metrics
No merged PRs in 30d

Description

### Overview

Assume a developer wants to call `Execute` on an `ICommand` from within another view model. Sure, bad practice but it's something that could happen in a larger project. Doing so will mean that the user forgot to check if the command can actually execute at all.

I vote that we change the `RelayCommand.Execute` function to check if it can execute before performing it's action.

### API breakdown

```csharp
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool CanExecute(object? parameter)
{
return this.canExecute?.Invoke() != false;
}

///
public void Execute(object? parameter)
{
if (!CanExecute(parameter)
{
return;
}

this.execute();
}
```

### Usage example

Take the following example where a property is set and `NotifyCanExecuteChanged` is invoked.

```csharp
public IRelayCommand BarCommand
{
get { return this.barCommand ??= new RelayCommand(this.Bar, this.CanBar); }
}

public bool Foo
{
get { return this.foo; }
set
{
this.SetProperty(ref this.foo, value);
this.BarCommand.NotifyCanExecuteChanged();
}
}

private void CanBar()
{
return someService.CanDoSomething();
}

private void Bar()
{
// Here, we are not checking if we CanBar
// But if a user calls BarCommand.Execute() outside of the scope of this view model they may forget to call BarCommand.CanExecute()
this.someService.DoSomething();
}
```

With the new changes in place, this will be avoided. Yes, there will be cases where `CanExecute` is executed twice; but it should theoretically be a quick operation anyways.

### Breaking change?

I'm not sure

### Alternatives

We can leave the `RelayCommand` as it is and sometimes forget to call `CanExecute` where required.

### Additional context

https://stackoverflow.com/a/6985124/22134768

### Help us help you

Yes, I'd like to be assigned to work on this item

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.