| 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:
- If the
CanExecutelogic is a method, keep CanExecuteMethod and remove CanExecuteProperty. - If it's a property, keep
CanExecutePropertyand removeCanExecuteMethod. Prefer a property when the declaring type implements INotifyPropertyChanged: the command then raises its CanExecuteChanged event when the property changes.
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.
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
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