c # Pub-Sub pattern

1

I am trying to use the Pub-Sub pattern to communicate the ViewModels of my application, but I must be doing something wrong, since I do not get the events to trigger.

The class with the code to handle the events is this:

    namespace App.Services
{
    using System;
    using System.Collections.Generic;

    public delegate void MessengerEventHandler<T>(object sender, MessengerEventArgs<T> args);

    public class MessengerEventArgs<T> : EventArgs
    {
        public T Item { get; set; }
        public MessengerEventArgs(T item)
        {
            Item = item;
        }
    }

    public enum MessengerType
    {
        NavigateToBalanceView
    }

    public static class Messenger<T>
    {
        private static Dictionary<MessengerType, MessengerEventHandler<T>> events = new Dictionary<MessengerType, MessengerEventHandler<T>>();

        public static void AddEvent(MessengerType name, MessengerEventHandler<T> handler)
        {
            if (!events.ContainsKey(name))
                events.Add(name, handler);
        }

        public static void RaiseEvent(MessengerType name, object sender, MessengerEventArgs<T> args)
        {
            if (events.ContainsKey(name) && events[name] != null)
                events[name](sender, args);
        }

        public static void RegisterEvent(MessengerType name, MessengerEventHandler<T> handler)
        {
            if (events.ContainsKey(name))
                events[name] += handler;
        }
    }
}

I have the implementation in the HomeViewModel to add an event like this:

namespace App.ViewModels
{
    using Base;
    using Models.DAL;
    using Services;
    using System.Linq;
    using System.Threading.Tasks;
    using Windows.UI.Xaml.Navigation;

    public class HomeViewModel : ViewModelBase
    {
        public event MessengerEventHandler<object> NavigateToBalanceViewHandler;

        public HomeViewModel()
        {
            Messenger<object>.AddEvent(MessengerType.NavigateToBalanceView, NavigateToBalanceViewHandler);
        }

        private decimal balance;
        public decimal Balance
        {
            get { return balance; }
            set { balance = value; RaisePropertyChanged(); }
        }

        public override Task OnNavigatedFrom(NavigationEventArgs args)
        {
            return null;
        }

        public override Task OnNavigatedTo(NavigationEventArgs args)
        {
            using (var db = new Context())
            {
                var bal = db.Balance.FirstOrDefault();
                if (bal == null)
                {
                    Messenger<object>.RaiseEvent(MessengerType.NavigateToBalanceView, this,
                        new MessengerEventArgs<object>(typeof(BalanceViewModel)));
                }
            }
            return null;
        }
    }
}

and in the MainViewModel to register the event, 'so:

public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            Messenger<object>.RegisterEvent(MessengerType.NavigateToBalanceView, NavigateToBalanceViewHandler);
        }

        private void NavigateToBalanceViewHandler(object sender, MessengerEventArgs<object> args)
        {

        }
}

When the event is added from the HomeViewModel, it registers correctly in the list, but always with the handler, "MessengerEventHandler" with null value, so when the event is triggered, it finds the type, but the value is always null.

Any clue where to look or what to check?

Thank you very much.

Edit, I'm based on the PubSub model that I found here:

Communication between ViewModels

    
asked by Darío Alonso 27.06.2016 в 17:33
source

1 answer

0

I recommend that you do not develop all the Pub-Sub pattern in your application, since there are frameworks that have already developed it and they take away a lot of work and make things easier for you. I use Prism, which has a PubSub development that works perfectly and also has a fairly large community where all the doubts are solved ( link )

I leave the link to the NuGet package in case you want to take a look: link

    
answered by 29.12.2016 в 13:05