Posted by: Zeeshan Amjad | January 8, 2012

Using Mediator to communicate between user controls: Part 3


In previous two parts we saw two different implementations of mediator design pattern here and here. Although in second part we remove the dependencies of specific user control from the mediator class and make it flexible enough to register as many client as you want using Register method. But we actually introduced one dependency for all the client. Now all of our client has to implement IMediatorClient interface.

Let’s take one step further and try to remove that dependency too. We change our mediator class little bit and instead of registering the mediator client, now we are going to register the call back method of every client. Our register method accept Action<object> type that is actually a callback method. And in send method we call all the method using DynamicInvoke method of Delegate class to call the callback method. Here is updated version of our mediator class.

Code Snippet
using System;
using System.Collections.Generic;

namespace MediatorUserControl
{
    public class Mediator
    {
        private List<Action<object>> actions = new List<Action<object>>();

        public Mediator()
        {
        }

        public void Register( Action<object> action)
        {
            actions.Add(action);
        }

        public void Send(object message)
        {
            foreach (var action in actions)
            {
                action.DynamicInvoke(message);
            }
        }
    }
}

 

Now we no more need to implement IMediatorClient interfaceSSSDFR55556 for our user controls. In our main window, we are registering the call back methods. Here is a piece of code to use the mediator.

Code Snippet
Mediator = new Mediator();
Mediator.Register(studentform.Notify);
Mediator.Register(studentlist.Notify);

studentform.Mediator = Mediator;
studentlist.Mediator = Mediator;

 

Here is a complete code of our main window.

Code Snippet
using System.Collections.ObjectModel;
using System.Windows;

namespace MediatorUserControl
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<Student> students = new ObservableCollection<Student>();

        public Mediator Mediator
        { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            students.Add(new Student() { ID = "1", FirstName = "Bob", LastName = "Smith", Degree = "Associate" });
            students.Add(new Student() { ID = "2", FirstName = "Alex", LastName = "White", Degree = "Certificate" });
            students.Add(new Student() { ID = "3", FirstName = "Chris", LastName = "Martin", Degree = "Master" });
            students.Add(new Student() { ID = "4", FirstName = "Michal", LastName = "Brown", Degree = "Bachlor" });

            Mediator = new Mediator();
            Mediator.Register(studentform.Notify);
            Mediator.Register(studentlist.Notify);

            studentform.Mediator = Mediator;
            studentlist.Mediator = Mediator;

            DataContext = students;
        }
    }
}

 

The code for both user controls are exactly same, the only difference is that now we are no more implementing the IMediatorClient interface and we even don’t need that interface in our project.

Here is a code for CustomizedList user control.

Code Snippet
using System.Windows;
using System.Windows.Controls;

namespace MediatorUserControl
{
    /// <summary>
    /// Interaction logic for CustomizedList.xaml
    /// </summary>
    public partial class CustomizedList : UserControl
    {
        public static readonly DependencyProperty SelectedStudentProperty =
            DependencyProperty.Register("SelectedStudent", typeof(Student), typeof(CustomizedList));

        public Student SelectedStudent
        {
            get { return (Student)GetValue(SelectedStudentProperty); }
            set { SetValue(SelectedStudentProperty, value); }
        }

        public Mediator Mediator
        { get; set;  }

        public CustomizedList()
        {
            InitializeComponent();
        }

        private void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SelectedStudent = list.SelectedItem as Student;
            Send(SelectedStudent);
        }

        public void Send(object message)
        {
            Mediator.Send(message);
        }

        public void Notify(object message)
        {

        }
    }
}

 

And here is a code of user control of StudentForm user control.

Code Snippet
using System.Windows.Controls;

namespace MediatorUserControl
{
    /// <summary>
    /// Interaction logic for StudentForm.xaml
    /// </summary>
    public partial class StudentForm : UserControl
    {
        public Mediator Mediator
        { get; set; }

        public StudentForm()
        {
            InitializeComponent();
        }

        public void Send(object message)
        {
        
        }

        public void Notify(object message)
        {
            Student student = message as Student;

            if (student != null)
            {
                DataContext = student;
            }
        }
    }
}

The output of this program is exactly same as previous program.

mediator_02_output

Advertisements

Responses

  1. Really interesting, I will take a look later to implement this in one of my personal project.

    Thank you for the second and third part of this article 😉

    Laurent

    • Thanks to like it. There is still room for improvement in it and I am already planning to write next part of it. Please keep giving me the feedback to improve it further.

      Regards
      Zeeshan Amjad

  2. […] of any interface by registering the call back method and execute it by calling DynamicInvoke method here. But there is still one problem in it that it will call all the register call back method whenever […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: