Domore.Notification
10.6.0
dotnet add package Domore.Notification --version 10.6.0
NuGet\Install-Package Domore.Notification -Version 10.6.0
<PackageReference Include="Domore.Notification" Version="10.6.0" />
<PackageVersion Include="Domore.Notification" Version="10.6.0" />
<PackageReference Include="Domore.Notification" />
paket add Domore.Notification --version 10.6.0
#r "nuget: Domore.Notification, 10.6.0"
#:package Domore.Notification@10.6.0
#addin nuget:?package=Domore.Notification&version=10.6.0
#tool nuget:?package=Domore.Notification&version=10.6.0
Domore.Notification
A small base class for implementing INotifyPropertyChanged, INotifyPropertyChanging, and INotifyDataErrorInfo in view models and other observable objects.
Install the package with dotnet add package Domore.Notification.
Raise change events
Derive from Notifier and call Change from property setters. Change compares the new value with the field. When the value is different, it raises PropertyChanging, sets the field, raises PropertyChanged, and returns true. When nothing changed, it raises no events and returns false.
using Domore.Notification;
public sealed class Person : Notifier {
public string FirstName {
get => _FirstName;
set => Change(ref _FirstName, value, nameof(FirstName), nameof(FullName));
}
private string _FirstName;
public int Age {
get => _Age;
set => Change(ref _Age, value);
}
private int _Age;
public string FullName => $"{FirstName}".Trim();
}
var person = new Person();
person.PropertyChanging += (s, e) => Console.WriteLine($"Changing: {e.PropertyName}");
person.PropertyChanged += (s, e) => Console.WriteLine($"Changed: {e.PropertyName}");
person.FirstName = "Ada"; // Changing: FirstName, Changing: FullName, Changed: FirstName, Changed: FullName
person.FirstName = "Ada"; // (no events)
person.Age = 36; // Changing: Age, Changed: Age
The property name comes from [CallerMemberName], so Change(ref field, value) is enough inside a setter. Any extra names passed after the property name are dependent properties, which are notified along with it. On .NET Framework 4.0, [CallerMemberName] isn't available, so pass the property name explicitly.
Change has overloads for the built-in numeric types, bool, char, string, and their nullable forms, which compare with == to avoid boxing. A generic overload handles every other type using EqualityComparer<T>.Default. Overloads that take PropertyChangedEventArgs let you reuse cached event arguments instead of property names.
Wrap values with Notified<T>
Notified<T> holds a property's value along with its name and cached event arguments, so the backing store and its name live in one place:
public sealed class Person : Notifier {
public string LastName {
get => _LastName.Value;
set => Change(_LastName, value, _FullName);
}
private readonly Notified<string> _LastName = new(nameof(LastName));
private readonly Notified<string> _FullName = new(nameof(FullName));
public string FullName => $"{LastName}".Trim();
}
Any Notified instances passed after the value are dependent properties that are notified along with it.
Raise events manually
NotifyPropertyChanged and NotifyPropertyChanging raise events directly. They accept property names, event arguments, or Notified instances, each with optional dependents. Calling NotifyPropertyChanged() with no arguments raises PropertyChanged with an empty property name, which tells bindings that all properties may have changed.
Suppress or veto changes
Set NotifyState to false to stop raising events without stopping values from changing. This is useful for batch updates:
public void Load(string firstName, int age) {
NotifyState = false;
try {
FirstName = firstName;
Age = age;
}
finally {
NotifyState = true;
}
NotifyPropertyChanged();
}
Override PreviewPropertyChange to veto a change before it happens. It's called on every Change call, before the equality check. Returning false leaves the value unchanged, raises no events, and makes Change return false:
public sealed class Document : Notifier {
public bool IsReadOnly { get; set; }
public string Title {
get => _Title;
set => Change(ref _Title, value);
}
private string _Title;
protected override bool PreviewPropertyChange(PropertyChangedEventArgs e) {
return IsReadOnly == false;
}
}
OnPropertyChanged and OnPropertyChanging are also virtual, for types that need to intercept every event.
Report validation errors
Derive from Notifier.WithErrorInfo to implement INotifyDataErrorInfo (not available on .NET Framework 4.0). Use AddError, RemoveError, and ClearErrors to manage errors. Each call that changes the set of errors raises ErrorsChanged.
public sealed class Account : Notifier.WithErrorInfo {
public string Email {
get => _Email;
set {
if (Change(ref _Email, value)) {
ClearErrors(nameof(Email));
if (value?.Contains("@") != true) {
AddError(nameof(Email), "Email must contain '@'.");
}
}
}
}
private string _Email;
}
HasErrors and GetErrors are protected on the class and exposed publicly through INotifyDataErrorInfo. A null or blank property name refers to errors for the entire object.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 is compatible. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net40 is compatible. net403 was computed. net45 was computed. net451 was computed. net452 was computed. net46 was computed. net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETCoreApp 3.1
- No dependencies.
-
.NETFramework 4.0
- No dependencies.
-
.NETFramework 4.6.2
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
net10.0
- No dependencies.
-
net6.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Domore.Notification:
| Package | Downloads |
|---|---|
|
Domore.Timing.Notification
Do More Timing Notification |
|
|
Domore.Processing
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.6.0 | 0 | 9/27/2026 |
| 10.5.0 | 33 | 9/26/2026 |
| 10.4.0 | 41 | 9/24/2026 |
| 10.3.1 | 89 | 9/18/2026 |
| 10.2.1 | 1,877 | 1/10/2026 |
| 10.2.0 | 169 | 1/10/2026 |
| 10.1.1 | 790 | 10/6/2025 |
| 10.1.0 | 316 | 9/22/2025 |
| 10.0.0 | 325 | 9/19/2025 |
| 9.7.0 | 634 | 1/29/2025 |
| 9.6.0 | 260 | 1/29/2025 |
| 9.5.0 | 286 | 1/24/2025 |
| 9.4.0.111 | 273 | 1/15/2025 |
| 9.3.0.110 | 333 | 12/12/2024 |
| 9.2.0.109 | 390 | 9/6/2024 |
| 9.1.2.108 | 289 | 8/17/2024 |
| 9.1.1.106 | 326 | 8/14/2024 |
| 9.1.0.105 | 317 | 8/1/2024 |
| 9.0.0.104 | 308 | 7/18/2024 |
| 8.3.0.103 | 304 | 7/17/2024 |