ObservableProperty
Another useful attribute from CommunityToolkit.Mvvm
, by using ObservableProperty
, we can get rid of ObservableObject.SetProperty
we mentioned earlier.
How is ObservableObject.SetProperty
been used
SetProperty
saves us from the boilerplate for each observable property.
cs
class Foo : ObservableObject
{
private bool _isChecked;
public bool IsChecked
{
get => _isChecked;
set => SetProperty(ref _isChecked, value); // [!code highlight]
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
ObservableProperty Approach
ObservableProperty
saves even more. It's empowered by source generator, which needs an extra partial
mark for emiting code at somewhere else.
cs
partial class Foo : ObservableObject // requires partial to emit code
{
[ObservableProperty] private bool _isChecked; // [!code highlight]
}
1
2
3
4
2
3
4
The code generated is like the following, performs the similar logic as SetProperty
.
cs
partial class Foo
{
/// <inheritdoc cref="_isChecked"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.3.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public bool IsChecked
{
get => _isChecked;
set
{
if (!global::System.Collections.Generic.EqualityComparer<bool>.Default.Equals(_isChecked, value)) // [!code highlight]
{
// also generates a lot methods for the field only.
OnIsCheckedChanging(value);
OnIsCheckedChanging(default, value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.IsChecked);
_isChecked = value;
OnIsCheckedChanged(value);
OnIsCheckedChanged(default, value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.IsChecked);
}
}
}
// ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26