Cross-platform toast notifications library for .NET. Messages, progress bars, Builder API, DI support, lifecycle events.
| API Docs | Docs | Migration Guide | Updates | WPF Sample |
|---|
| Package | Target | Description |
|---|---|---|
| Notification.Core | netstandard2.0 |
Platform-agnostic core: interfaces, Builder API, events, queue, DI |
| Notification.Wpf | net10/9/8/4.8-windows |
WPF implementation with full UI: toasts, progress bars, custom content |
| Notification.Console | netstandard2.0 |
Console implementation with colored terminal output |
| Notification.AvaloniaUI | net8.0 |
Avalonia UI implementation via WindowNotificationManager |
| Notification.Maui | net10.0-* |
.NET MAUI implementation via CommunityToolkit Snackbar/Toast and native ActionSheet dialogs |
// WPF (includes Core automatically)
Install-Package Notification.Wpf
// Or use Core directly for cross-platform
Install-Package Notification.CoreUI
// Platform-specific
Install-Package Notification.Console
Install-Package Notification.AvaloniaUI
Install-Package Notification.Maui
// Works on any platform via INotificationService
service.Show(NotificationBuilder
.Create("Success", "Operation completed!")
.AsSuccess()
.ExpiresInSeconds(5)
.WithPriority(NotificationPriority.High)
.OnClick(() => Console.WriteLine("Clicked"))
.Build());Awaitable overloads on INotificationService complete when a notification closes,
with a structured close reason.
NotificationCloseResult r = await manager.ShowAsync("Saved", NotificationType.Success);
if (r.Reason == NotificationCloseReason.ActionButton) DoNext();For explicit dialogs use ShowDialogAsync with a Buttons[] collection:
NotificationCloseResult r = await manager.ShowDialogAsync(new NotificationRequest
{
Title = "Delete file?",
Message = path,
Type = NotificationType.Warning,
Buttons = new[]
{
new NotificationButton { Id = "delete", Content = "Delete", Role = NotificationButtonRole.Destructive },
new NotificationButton { Id = "cancel", Content = "Cancel", Role = NotificationButtonRole.Negative }
}
}, cancellationToken: ct);
if (r.Reason == NotificationCloseReason.ActionButton && r.ButtonId == "delete")
DeleteFile();See Migration.md for upgrading from v10.
Version 10.0 is fully backward compatible — existing code keeps working. Two legacy APIs are now
marked [Obsolete] and have clearer replacements:
// Progress: tuple API -> Report(...) overloads
progress.Report(50, "half done", "Working");
// ShowProgressBar: 16 positional parameters -> ProgressBarOptions
manager.ShowProgressBar(new ProgressBarOptions { Title = "Working...", ProgressColor = NotificationColor.LimeGreen });
// Show: up to 18 positional parameters -> NotificationBuilder (recommended, the old overloads still work)
manager.Show(NotificationBuilder.Create("Title", "Message").AsSuccess().ExpiresInSeconds(5).Build());➡️ Full step-by-step guide with before/after examples and parameter mapping tables: Migration Guide
// WPF
services.AddWpfNotifications(config =>
{
config.DefaultExpirationTime = TimeSpan.FromSeconds(5);
config.MessagePosition = NotificationPosition.BottomRight;
});
// Console
services.AddConsoleNotifications();
// Avalonia
services.AddAvaloniaNotifications();
// MAUI (in MauiProgram.cs)
builder
.UseMauiCommunityToolkit() // required by Notification.Maui
.UseMauiNotifications(config =>
{
config.DefaultExpirationTime = TimeSpan.FromSeconds(3);
});var events = serviceProvider.GetRequiredService<INotificationEventService>();
events.NotificationShown += (s, e) => Log($"Shown: {e.Title}");
events.NotificationClicked += (s, e) => Log($"Clicked: {e.NotificationId}");
events.NotificationClosed += (s, e) => Log($"Closed: {e.Stage}");All existing WPF APIs continue to work:
var notificationManager = new NotificationManager();
// Simple message
notificationManager.Show("Title", "Message", NotificationType.Success);
// Inside application window
notificationManager.Show("Title", "Message", NotificationType.Warning, "WindowArea");
// Progress bar
using var progress = notificationManager.ShowProgressBar(new ProgressBarOptions { Title = "Processing..." });
for (var i = 0; i <= 100; i++)
{
progress.Report(i, $"Step {i}"); // tuple-free Report overload
await Task.Delay(30, progress.Cancel);
}See the Migration Guide if you still use the 16-parameter
ShowProgressBar(...)or the tuple-based progress API.
None, Information, Success, Warning, Error, Notification
xmlns:notifications="clr-namespace:Notification.Wpf.Controls;assembly=Notification.Wpf"
<notifications:NotificationArea x:Name="WindowArea" Position="TopLeft" MaxItems="3"/>src/
Notification.Core (netstandard2.0) <- zero UI dependencies
├── Interfaces (INotificationService, INotificationConfiguration)
├── Builder API (NotificationBuilder -> NotificationRequest)
├── Events (INotificationEventService, lifecycle tracking)
├── Queue (INotificationQueue with priorities)
└── DI extensions (AddNotifications)
Notification.Wpf (net10/9/8/4.8-windows) <- depends on Core
Notification.Console (netstandard2.0) <- depends on Core
Notification.Avalonia (net8.0) <- depends on Core
Notification.Maui (net10.0-*) <- depends on Core
Tests/
Notification.Core.Tests
Notification.Console.Tests
Notification.Wpf.Tests
Samples/
Notification.Wpf.Sample
Notification.Console.Sample
Notification.Avalonia.Sample
Notification.Maui.Sample
DocFx/ <- DocFX API documentation
dotnet test Tests/Notification.Core.Tests
dotnet test Tests/Notification.Console.Tests
dotnet test Tests/Notification.Wpf.Tests
134 unit tests covering Builder API, events, queue, configuration, adapters, and platform implementations.
Notification window stays open after closing the app:
Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;Using in non-WPF hosts (WinForms, Console, VSTO, tests):
Since v9.0, Application.Current null-checks are built-in. The library works correctly when hosted in WinForms, console applications, Office add-ins, and other non-WPF processes without additional configuration.
MAUI on Windows — notification appearance:
On Windows, CommunityToolkit.Maui Snackbar uses native AppNotification (toast). The app name and icon shown in the notification center are determined by Windows app registration, not by the Snackbar API. SnackbarOptions colors are also ignored on Windows — the library uses emoji prefixes (✅ Snackbar; notifications without buttons use Toast to avoid an empty button area. The async ShowAsync/ShowDialogAsync dialog path (Buttons[]) instead renders a native ActionSheet, which has a different appearance from the legacy Snackbar/Toast path described above.
MAUI — platform limitations:
The legacy fire-and-forget Show() path (Snackbar/Toast) does not support multiple buttons, images, custom content, or progress bars — only one action button (LeftButtonContent) is supported, and RightButtonContent, PlatformImage, and Icon are ignored. The async ShowDialogAsync/ShowAsync path with Buttons[] does not have this restriction: it renders a native ActionSheet supporting any number of buttons. Images, custom Content, and progress bars remain unsupported on both paths; for those, use the WPF or Avalonia implementations.
This project was forked from https://github.com/Federerer/Notifications.Wpf
Project was re-released due to lack of owner interest in updating it.



