| Severity | Error |
| Reported by | Metalama.Patterns.Wpf |
| Message | The '<Member>' <Kind> has an invalid signature and cannot be used as a <Role> for <TargetDescription>'<Target>' <AsRequired>by the '<NamingConvention>' naming convention.<InvalidityReason> |
Cause
The WPF aspects find helper members by name:
- The [Command] aspect looks for a can-execute method or property. For a command named
Save, the default names areCanExecuteSave,CanSave, andIsSaveEnabled. You can also set the name with CanExecuteMethod or CanExecuteProperty. - The [DependencyProperty] aspect looks for a property-changed method and a validate method. For a property named
Foo, the default names areOnFooChangedandValidateFoo. You can also set the names with PropertyChangedMethod and ValidateMethod.
Metalama reports LAMA5204 on a member that has the expected name but a signature the aspect can't use, when no other member with a valid signature is found for the same role. The aspect isn't applied to the target. The signature rules are:
- A can-execute method must return
bool, must not be generic, and must have no parameter or one parameter passed by value orin. - A can-execute property must be of type
booland have a getter. - A property-changed method must return
voidand use one of the signatures listed in WPF dependency properties, for example no parameter, the new value, or the old and new values. - A validate method must return
voidand use one of the signatures listed in WPF dependency properties, for exampleValidateFoo( int value ).
In the message, <Member> and <Kind> are the invalid member and its kind, <Role> is the role, such as can-execute property or property-changed method, <Target> is the aspect's target, <NamingConvention> is the naming convention, and <InvalidityReason> explains the signature rule. <AsRequired> is as required when the member is required, for example because its name was set explicitly in the attribute.
In the following example, the Save command finds the method CanSave by naming convention, but this method returns int instead of bool.
1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5204.Error;
4
5public partial class DocumentViewModel
6{
7 private int _unsavedChanges = 1;
8
9 // Error: a can-execute method must return bool.
Error LAMA5204: The 'DocumentViewModel.CanSave()' method has an invalid signature and cannot be used as a can-execute method for [Command] method 'DocumentViewModel.Save()' by the 'default' naming convention. The method must not be generic, must return bool and may optionally have a single parameter of any type, but which must not be a ref or out parameter.
10 private int CanSave() => this._unsavedChanges;
11
12 [Command]
13 public void Save() => this._unsavedChanges = 0;
14}
15
Resolution
- Fix the signature of the member so that it follows the rules above, for example change the return type of
CanSavetobool. - If the member isn't meant to be a helper of the aspect, rename it so that it no longer matches the naming convention.
- If you set the member name explicitly in the attribute, check that it names the right member.
In the following example, CanSave returns bool.
1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5204.Fixed;
4
5public partial class DocumentViewModel
6{
7 private int _unsavedChanges = 1;
8
9 // Fixed: the can-execute method returns bool.
10 private bool CanSave() => this._unsavedChanges > 0;
11
12 [Command]
13 public void Save() => this._unsavedChanges = 0;
14}
15
1using Metalama.Patterns.Wpf;
2
3namespace Doc.LAMA5204.Fixed;
4
5public partial class DocumentViewModel
6{
7 private int _unsavedChanges = 1;
8
9 // Fixed: the can-execute method returns bool.
10 private bool CanSave() => this._unsavedChanges > 0;
11
12 [Command]
13 public void Save() => this._unsavedChanges = 0;
14
15 public DocumentViewModel()
16 {
17 SaveCommand = DelegateCommandFactory.CreateDelegateCommand(Save, CanSave);
18 }
19
20 public DelegateCommand SaveCommand { get; }
21}
22