Guest User

MVVM messaging example

a guest
Apr 16th, 2023
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.16 KB | None | 0 0
  1. A more professional solution is to let the view model publish events in different contexts e.g. DataSaved or error events like FileNotFound.
  2. The view becomes the observer and converts those events to messages for the user.
  3. You can move this responsibilities to an e.g. Messenger class. Also consider to use IDs that map to actual messages for such application events.
  4. This pattern becomes even more powerful if those events are published and observed via an event aggregator. This decouples the view from view model: adding more event sources will not break the observer classes, since the aggregator allows anonymous event observation.
  5.  
  6. MessageId.cs
  7.  
  8. enum MessageId
  9. {
  10.   Default = 0,
  11.   FileNotFound
  12. }
  13.  
  14. EventAggregator.cs
  15.  
  16. class EventAggregator
  17. {
  18.   // Register for all events named e.g. "ApplicationEvent" and of type 'EventHandler<ApplicationEventArgs>'
  19.   public void RegisterListener<TArgs>(string eventName, EventHandler<TArgs> callBack)
  20.   {
  21.     ...
  22.   }
  23.  
  24.   public void RegisterPublisher(object eventSource, string eventName)
  25.   {
  26.     ...
  27.   }
  28. }
  29.  
  30. ApplicationEventArgs.cs
  31. Superclass for all custom application events args
  32.  
  33. class ApplicationEventArgs : EventArgs
  34. {
  35.   public MessageId Id { get; }
  36.   public ApplicationEventArgs(MessageId id) => this.Id = id;
  37. }
  38.  
  39. View Model
  40.  
  41. MainViewModel.cs
  42.  
  43. class MainViewModel : IViewModel
  44. {
  45.   public event EventHandler<ApplicationEventArgs> ApplicationEvent;
  46.  
  47.   public MainViewModel(EventAggregator eventAggregator)
  48.   {
  49.     // Broadcast event using the event aggregator
  50.     eventaggregator.RegisterPublisher(this, nameof(this.ApplicationEvent));
  51.   }
  52.  
  53.   private void OnFileNotFound()
  54.     => OnApplicationEvent(MessageId.FileNotFound);
  55.  
  56.   protected virtual void OnApplicationEvent(MessageId messageId)
  57.     => this.ApplicationEvent?.Invoke(this, new ApplicationEventArgs(messageId));
  58. }
  59.  
  60. View
  61.  
  62. Messenger.cs
  63.  
  64. class Messenger
  65. {
  66.   // Notify e.g. MainWindow and deliver the resolved message
  67.   public event EventHandler<MessageReceivedEventArgs> MessageReceived;
  68.  
  69.   public Messenger(EventAggregator eventAggregator)
  70.   {
  71.     // Observe all ApplicationEvent events
  72.     eventAggregator.RegisterListener(nameof(IViewModel.ApplicationEvent), OnApplicationEvent);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
  73.   }
  74.  
  75.   private void OnApplicationEvent(object sender, ApplicationEventArgs e)
  76.   {
  77.     // Read (localized) messages e.g. from a JSON that stores messages as key-value-pair
  78.     Dictionary<int, string> messages = ReadJsonMessageSource();
  79.     if (messages.TryGetValue((int)e.Id, out string message))
  80.     {
  81.       DispatchMessage(message);
  82.     }
  83.   }
  84.  
  85.   private void DispatchMessage(string messageText)
  86.   {
  87.     // Create a complex message object
  88.     var message = new Message()
  89.     {
  90.       Text = messageText,
  91.       Image = GetMessageImage()
  92.       Category = ...
  93.     }
  94.  
  95.     OnMessageReceived(message);
  96.   }
  97.  
  98.   private void OnMessageReceived(Message message)
  99.     => this.MessageReceived?.Invoke(this, new MessageReceivedEventArgs(message));
  100. }
  101.  
  102. MainWindow.xaml.cs
  103.  
  104. partial class MainWindow : Window
  105. {
  106.   private Messenger Messenger { get; }
  107.  
  108.   public MainWindow()
  109.   {
  110.     InitializeComponent();
  111.  
  112.     this.Messenger = new Messenger();
  113.     this.Messenger.MessageReceived += OnMessageReceived;
  114.   }
  115.  
  116.   private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
  117.   {
  118.     var messageBox = new MessageBox(e.Message);
  119.     messageBox.ShowDialog();
  120.   }
  121. }
  122.  
Advertisement
Add Comment
Please, Sign In to add comment