Open sandboxFocusImprove this doc

LAMA5201: A command can't have both a can-execute method and a can-execute property

Severity Error
Reported by Metalama.Patterns.Wpf
Message The CanExecuteMethod and CanExecuteProperty properties cannot both be defined at the same time.

Cause

The [Command] aspect generates a WPF command property from a method. The command's CanExecute logic comes from a single member: either a bool method or a bool property. You can name this member explicitly with the CanExecuteMethod or the CanExecuteProperty property of the attribute, but not with both.

Metalama reports LAMA5201 on the target method when both properties are set, for example [Command( CanExecuteMethod = "CanSave", CanExecuteProperty = "IsSaveEnabled" )]. The aspect then stops: it doesn't generate the command property and doesn't report any other diagnostic for this method.

In the following example, the Save command sets both CanExecuteMethod and CanExecuteProperty.

1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5201.Error;
4
5public partial class DocumentViewModel
6{
7    private bool _isDirty = true;
8
9    private bool CanSave() => this._isDirty;
10
11    private bool IsSaveEnabled => this._isDirty;
12
13    // Error: the attribute sets both CanExecuteMethod and CanExecuteProperty.
14    [Command( CanExecuteMethod = "CanSave", CanExecuteProperty = "IsSaveEnabled" )]
    Error LAMA5201: The CanExecuteMethod and CanExecuteProperty properties cannot both be defined at the same time.

15    public void Save() => this._isDirty = false;
16}
17

Resolution

Keep only one of the two properties in the [Command] attribute:

You can also remove both properties and rely on the naming convention: for a command named Save, the aspect looks for a member named CanExecuteSave, CanSave, or IsSaveEnabled.

In the following example, only CanExecuteMethod remains.

Source Code
1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5201.Fixed;
4
5public partial class DocumentViewModel
6{
7    private bool _isDirty = true;
8
9    private bool CanSave() => this._isDirty;
10
11    private bool IsSaveEnabled => this._isDirty;
12
13    // Fixed: only CanExecuteMethod is set.
14    [Command( CanExecuteMethod = "CanSave" )]
15    public void Save() => this._isDirty = false;
16}
17
Transformed Code
1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5201.Fixed;
4
5public partial class DocumentViewModel
6{
7    private bool _isDirty = true;
8
9    private bool CanSave() => this._isDirty;
10
11    private bool IsSaveEnabled => this._isDirty;
12
13    // Fixed: only CanExecuteMethod is set.
14    [Command(CanExecuteMethod = "CanSave")]
15    public void Save() => this._isDirty = false;
16
17    public DocumentViewModel()
18    {
19        SaveCommand = DelegateCommandFactory.CreateDelegateCommand(Save, CanSave);
20    }
21
22    public DelegateCommand SaveCommand { get; }
23}
24

See also