Enterwell Client WPF - Notifications

repository·master·Indexed 19 days ago

https://github.com/enterwell/wpf.notifications

A notification system for WPF applications featuring a fluent API for creating messages with badges, custom colors, and interactive buttons. The library includes components such as NotificationMessageManager for queueing, NotificationMessageContainer for visual display, and support for custom overlays, animations, and additional UI content injection.

Tokens
2K
Snippets
6
Records
7
Agent score
15%

What's inside Enterwell.Clients.Wpf.Notifications

  1. How the notification system components work together

    master

    The notification system is composed of several key parts:

    • NotificationMessage: The primary UI control representing a single notification. It consists of a badge (left), a message (center), and buttons (right).
    • NotificationMessageButton: A button control used for user interaction within a notification.
    • NotificationMessageFactory: A factory used to instantiate the controls.
    • NotificationMessageManager: The central manager responsible for queueing and dismissing notifications. It uses the factory to create messages.
    • NotificationMessageContainer: A UI control that must be placed in your application's view (e.g., the Main Window). It is assigned a NotificationMessageManager and handles the visual stack and lifecycle of all queued notifications.

    To use the system, place a NotificationMessageContainer in your XAML and bind its Manager property to an instance of NotificationMessageManager (provided via DI, ViewModel, or code-behind).

    // In code-behind
    this.Manager = new NotificationMessageManager();
    
    // In XAML
    <controls:NotificationMessageContainer Manager="{Binding Manager}" />
  2. Create a simple notification using the fluent API

    master

    Use the NotificationMessageManager.CreateMessage() method to start a fluent builder chain. You can set the accent color, background, badge text, and message content.

    To add buttons, use .WithButton(content, callback). If you want a button to also dismiss the notification when clicked, chain .Dismiss() before .WithButton().

    Finally, call .Queue() to send the message to the NotificationMessageContainer for display.

    manager.CreateMessage()
           .Accent("#1751C3")
           .Background("#333")
           .HasBadge("Info")
           .HasMessage("Update will be installed on next application restart.")
           .Dismiss().WithButton("Update now", button => { })
           .Dismiss().WithButton("Release notes", button => { })
           .Dismiss().WithButton("Later", button => { })
           .Queue(); 
  3. Add custom additional content to a notification

    master

    You can inject custom UI elements into specific locations within the NotificationMessage using .WithAdditionalContent(ContentLocation, UIElement).

    Supported ContentLocation values:

    • Top
    • Bottom
    • Left
    • Right
    • Main
    • AboveBadge
    manager.CreateMessage()
           .Accent("#1751C3")
           .Background("#333")
           .HasBadge("Info")
           .HasHeader("Update available")
           .HasMessage("Update will be installed on next application restart.")
           .Dismiss().WithButton("Update now", button => { })
           .Dismiss().WithButton("Later", button => { })
           .WithAdditionalContent(ContentLocation.Bottom,
           new Border
           {
               BorderThickness = new Thickness(0,1,0,0),
               BorderBrush = new SolidColorBrush(Color.FromArgb(128, 28, 28, 28)),
               Child = new CheckBox
               {
                   Margin = new Thickness(12, 8, 12, 8),
                   HorizontalAlignment = HorizontalAlignment.Left,
                   Content = "Don't show again"
               }
           })
           .Queue();
  4. Enable notification animations

    master

    Animations are an opt-in feature. You can enable them and configure the durations using the following methods on the message builder:

    • .Animates(bool): Enables or disables animations.
    • .AnimationInDuration(double): Sets the duration for the entrance animation.
    • .AnimationOutDuration(double): Sets the duration for the exit animation.
    manager
        ...
        .Animates(true)
        .AnimationInDuration(0.75)
        .AnimationOutDuration(2)
        ...
  5. Add a custom overlay to a notification

    master

    Use .WithOverlay(UIElement) to place a custom control over the notification. This is useful for showing progress bars or status indicators.

    Note: When using an overlay, ensure the overlay control has IsHitTestVisible = false if it covers areas where user interaction (like buttons) is required, to prevent it from intercepting mouse events.

    manager.CreateMessage()
           .Accent("#F15B19")
           .Background("#F15B19")
           .HasHeader("Lost connection to server")
           .HasMessage("Reconnecting...")
           .WithOverlay(new ProgressBar
           {
               VerticalAlignment = VerticalAlignment.Bottom,
               HorizontalAlignment = HorizontalAlignment.Stretch,
               Height = 3,
               BorderThickness = new Thickness(0),
               Foreground = new SolidColorBrush(Color.FromArgb(128, 255, 255, 255)),
               Background = Brushes.Transparent,
               IsIndeterminate = true,
               IsHitTestVisible = false
           })
           .Queue();
  6. Create notifications without the fluent builder

    master

    If you prefer not to use the extension methods or the fluent builder, you can use the NotificationMessageBuilder directly or instantiate the NotificationMessage control manually.

    Using NotificationMessageBuilder:

    builder.Manager = this.Manager;
    builder.Message = this.Manager.Factory.GetMessage();
    builder.SetAccent(Brushes.DodgerBlue);
    builder.SetBackground(Brushes.DimGray);
    builder.SetBadge("Info");
    builder.HasMessage("This notification is built without extension methods.");
    
    var notificationButton = this.Manager.Factory.GetButton();
    notificationButton.Content = "This is much longer";
    notificationButton.Callback = (button) =>
    {
        this.Manager.Dismiss(builder.Message);
    };
    
    builder.AddButton(notificationButton);
    builder.Manager.Queue(builder.Message);

    Manual instantiation:

    {
        Message = "Works event without message builder",
        BadgeText = "Info",
        AccentBrush = Brushes.Orange,
        Background = Brushes.Black,
        Buttons = new ObservableCollection<object>
        {
            new NotificationMessageButton()
            {
                Content = "Great!",
                Callback = button => { }
            }
        }
    });