Skip to content

Notification Popups

Damian edited this page Feb 5, 2023 · 7 revisions

Using Avalonia's Popup Notification can easily be integrated into your Prism.Avalonia project. Below, we'll show you just how to do that.

For a full sample, check out the Learn Prism Avalonia Outlookish sample project which performs this exact implementation.

Usage

Add to your ViewModel:

using Prism.Commands;
using SampleApp.Services;

namespace SampleApp.ViewModels;

public class DashboardViewModel : ViewModelBase
{
  private readonly INotificationService _notificationService;

  public DashboardViewModel(INotificationService notifyService)
  {
    _notificationService = notifyService;
    Title = "Dashboard";
  }

  public DelegateCommand CmdNotification => new(() =>
  {
    _notification.Show("Hello Prism!", "Notification Pop-up Message.");

    // Alternate OnClick action
    ////_notification.Show("Hello Prism!", "Notification Pop-up Message.", () =>
    ////{
    ////  // Action to perform
    ////});
  });
}

Implementing Avalonia Notification

To implement, we're going to need to create/modify a few files in your project. First, we're going to need to create a service for calling the Notifications. Next, we need to add a wire-up code in your Main Window class. And finally, register the service.

  1. Services\INotificationService.cs
  2. Services\NotificationService.cs
  3. Views\MainWindow.axaml.cs
  4. App.xaml.cs

Notification Service

We'll start by creating an INotificationService interface and then the NotificationService class.

INotificationService

using System;
using Avalonia.Controls;

namespace SampleApp.Services
{
  public interface INotificationService
  {
    int NotificationTimeout { get; set; }

    void SetHostWindow(Window window);

    void Show(string title, string message, Action? onClick = null);
  }
}

NotificationService

using System;
using System.Reactive.Concurrency;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using ReactiveUI;

namespace SampleApp.Services
{
  public class NotificationService : INotificationService
  {
    private int _notificationTimeout = 10;
    private WindowNotificationManager? _notificationManager;

    public int NotificationTimeout
    {
      get => _notificationTimeout;
      set
      {
        _notificationTimeout = (value < 0) ? 0 : value;        
      }
    }

    /// <summary>Set the host window.</summary>
    /// <param name="hostWindow">Parent window.</param>
    public void SetHostWindow(Window hostWindow)
    {
      var notificationManager = new WindowNotificationManager(hostWindow)
      {
        Position = NotificationPosition.BottomRight,
        MaxItems = 4,
        Margin = new Thickness(0, 0, 15, 40)
      };

      _notificationManager = notificationManager;
    }

    /// <summary>Display the notification.</summary>
    /// <param name="title">Title.</param>
    /// <param name="message">Message.</param>
    /// <param name="onClick">Optional OnClick action.</param>
    public void Show(string title, string message, Action? onClick = null)
    {
      if (_notificationManager is { } nm)
      {
        // WARNING: If you have a threading issue, try using `Dispatcher.UIThread..` instead of `RxApp..`
        // Dispatcher.UIThread.InvokeAsync(() =>
        // {
        RxApp.MainThreadScheduler.Schedule(() =>
        {
          nm.Show(
            new Notification(
              title,
              message,
              NotificationType.Information,
              TimeSpan.FromSeconds(_notificationTimeout),
              onClick));
        });
      }
    }
  }
}

Main Window

Step 2,

using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Prism.Ioc;
using SampleApp.Services;

namespace SampleApp.Views
{
  public partial class MainWindow : Window
  {
    private WindowNotificationManager _notificationArea;

    public MainWindow()
    {
      InitializeComponent();
#if DEBUG
      this.AttachDevTools();
#endif

      // Initialize the WindowNotificationManager with the MainWindow
      var notifyService = ContainerLocator.Current.Resolve<INotificationService>();
      notifyService.SetHostWindow(this);
    }

    private void InitializeComponent()
    {
      AvaloniaXamlLoader.Load(this);
    }
  }
}

App.axml.cs

Finally, register the Notification Service that you've created in Step-1 with Prism.

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
      // Services
      containerRegistry.RegisterSingleton<INotificationService, NotificationService>();

      ...
    }
Clone this wiki locally