WPF – Messenger

Messenger uses Mediator design pattern to communicate between ViewModels. 
Messenger class decreases coupling between ViewModels. Every ViewModel can communicate with another viewmodel without any association between them.

Custom Messenger

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommandAndMessenger.Common
{
    public class CustomMessenger
    {
        private static Lazy<CustomMessenger> instance = new Lazy<CustomMessenger>();

        public event EventHandler<MessageEventHandler> EventMessage;

        public static CustomMessenger Instance
        {
            get { return instance.Value;  }
        }

        public void SendMessage(object message)
        {
            if (EventMessage != null)
            {
                EventMessage(this, new MessageEventHandler(message));
            }
        }
    }
}

Prism Messenger

using Microsoft.Practices.Prism.PubSubEvents;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VMCommunication.Model;

namespace VMCommunication
{
    public class A : IViewModel
    {
        public A()
        {
            PrismMessenger.Default.GetEvent<PubSubEvent>().Subscribe((x) => Refresh(x));
            PrismMessenger.Default.GetEvent<PubSubEvent>().Subscribe((x) => NameChanged(x));
        }

        private void NameChanged(string x)
        {
            Debug.WriteLine($"Name is Changed to {x}");
        }

        public void Refresh(Item i)
        {
            Debug.WriteLine("This is A Class object");
        }
    }
}

Example:

internal class Main: SimpleItem
    {
        public Main():
            base("My Sample Application")
        {

            OpenFileCommand = new CustomCommand((x) => FileOpen(x), (x)=> true);
            CloseApplicationCommand = new CustomCommand((x) => CloseApplication(x), (x) => true);
            CustomMessenger.Instance.EventMessage += (s,e) => DisplayName = e.Message as string;
            CustomMessenger.Instance.EventMessage += (s, e) => Selected = e.Message as Student;
        }

        public ICommand OpenFileCommand { get; set; }

        public ICommand CloseApplicationCommand { get; set; }

        private void FileOpen(object para)
        {
            CustomMessenger.Instance.SendMessage("File Open is Selected");
            Student steve = new Student()
            {
                Name = "Steve",
                City = "Slough",
            };
            CustomMessenger.Instance.SendMessage(steve);
        }

        private void CloseApplication(object para)
        {
            CustomMessenger.Instance.SendMessage("Close Application is Selected");
            Student markus = new Student()
            {
                Name = "markus",
                City = "Reading",
            };
            CustomMessenger.Instance.SendMessage(markus);
        }

        private Student student;

        public Student Selected
        {
            get { return student; }
            set { SetValue(ref student,value, nameof(Selected)); }
        }

    }

XAML:

<Window x:Class="CommandAndMessenger.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:infra="clr-namespace:CommandAndMessenger.Infrastructure"
        xmlns:local="clr-namespace:CommandAndMessenger"
        xmlns:m="clr-namespace:CommandAndMessenger.Model"
        mc:Ignorable="d"
        Title="{Binding DisplayName}"
        Height="350" Width="525"
        >
    <StackPanel>
        <StackPanel.Resources>
            <DataTemplate DataType="{x:Type m:Student}">
                <StackPanel Orientation="Vertical">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="Name"/>
                        <TextBox Text="{Binding Name}"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="City"/>
                        <TextBox Text="{Binding City}"/>
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </StackPanel.Resources>
        <Button Content="Click Me for Context Menu" MinWidth="200">
            <i:Interaction.Behaviors>
                <infra:ClickContextMenuBehavior  />
            </i:Interaction.Behaviors>
            <Button.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Open File" Command="{Binding OpenFileCommand}"/>
                    <MenuItem Header="Close Application" Command="{Binding CloseApplicationCommand}"/>
                </ContextMenu>
            </Button.ContextMenu>
        </Button>
        <ContentControl Content="{Binding Selected}" />
    </StackPanel>
</Window>

Leave a Reply

Your e-mail address will not be published. Required fields are marked *