Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- A more professional solution is to let the view model publish events in different contexts e.g. DataSaved or error events like FileNotFound.
- The view becomes the observer and converts those events to messages for the user.
- 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.
- 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.
- MessageId.cs
- enum MessageId
- {
- Default = 0,
- FileNotFound
- }
- EventAggregator.cs
- class EventAggregator
- {
- // Register for all events named e.g. "ApplicationEvent" and of type 'EventHandler<ApplicationEventArgs>'
- public void RegisterListener<TArgs>(string eventName, EventHandler<TArgs> callBack)
- {
- ...
- }
- public void RegisterPublisher(object eventSource, string eventName)
- {
- ...
- }
- }
- ApplicationEventArgs.cs
- Superclass for all custom application events args
- class ApplicationEventArgs : EventArgs
- {
- public MessageId Id { get; }
- public ApplicationEventArgs(MessageId id) => this.Id = id;
- }
- View Model
- MainViewModel.cs
- class MainViewModel : IViewModel
- {
- public event EventHandler<ApplicationEventArgs> ApplicationEvent;
- public MainViewModel(EventAggregator eventAggregator)
- {
- // Broadcast event using the event aggregator
- eventaggregator.RegisterPublisher(this, nameof(this.ApplicationEvent));
- }
- private void OnFileNotFound()
- => OnApplicationEvent(MessageId.FileNotFound);
- protected virtual void OnApplicationEvent(MessageId messageId)
- => this.ApplicationEvent?.Invoke(this, new ApplicationEventArgs(messageId));
- }
- View
- Messenger.cs
- class Messenger
- {
- // Notify e.g. MainWindow and deliver the resolved message
- public event EventHandler<MessageReceivedEventArgs> MessageReceived;
- public Messenger(EventAggregator eventAggregator)
- {
- // Observe all ApplicationEvent events
- eventAggregator.RegisterListener(nameof(IViewModel.ApplicationEvent), OnApplicationEvent);
- }
- private void OnApplicationEvent(object sender, ApplicationEventArgs e)
- {
- // Read (localized) messages e.g. from a JSON that stores messages as key-value-pair
- Dictionary<int, string> messages = ReadJsonMessageSource();
- if (messages.TryGetValue((int)e.Id, out string message))
- {
- DispatchMessage(message);
- }
- }
- private void DispatchMessage(string messageText)
- {
- // Create a complex message object
- var message = new Message()
- {
- Text = messageText,
- Image = GetMessageImage()
- Category = ...
- }
- OnMessageReceived(message);
- }
- private void OnMessageReceived(Message message)
- => this.MessageReceived?.Invoke(this, new MessageReceivedEventArgs(message));
- }
- MainWindow.xaml.cs
- partial class MainWindow : Window
- {
- private Messenger Messenger { get; }
- public MainWindow()
- {
- InitializeComponent();
- this.Messenger = new Messenger();
- this.Messenger.MessageReceived += OnMessageReceived;
- }
- private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
- {
- var messageBox = new MessageBox(e.Message);
- messageBox.ShowDialog();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment