Pasando información entre dos ViewModel en WPF


Muy buenos días a todos,

No suelo escribir sobre esta temática porque no es mi herramienta habitual de trabajo, aunque hoy quiero compartir con vosotros un tema relacionado con WPF al que le he tenido que dedicar algo de tiempo. Durante un desarrollo me ha surgido la necesidad, más que habitual por otro lado, de tener que pasar información entre dos ViewModel.

Después de buscar información por internet, comprobé que la mejor forma de hacerlo era a través de un sistema de paso de mensajes, de manera que el ViewModel origen, enviara un mensaje a un receptor, el ViewModel que necesita la información. Un artículo muy completo sobre este tema lo podéis encontrar en el siguiente enlace:

https://msdn.microsoft.com/en-us/magazine/dn745866.aspx

Por el motivo que sea, cuando quiero comprender algo, necesito hacerlo por mí mismo, y para entender la base del funcionamiento de este sistema, necesito verlo con un ejemplo muy sencillo, para luego poder usar los frameworks y librerías más avanzadas y poder entender qué hace.

Así que, no con el objetivo de reinventar la rueda, sino de comprender superficialmente como funciona un sistema de paso de mensajes, para un proyecto que tengo he creado una clase que lo implementa de una forma muy sencilla. Obviamente, es muy limitada y usando una librería como la que se sugiere en el enlace las posibilidades son muchísimas, no os recomiendo usar esta clase en un proyecto real, de dimensiones importantes. No obstante para probar, aquí tenéis, porque funcionar, funciona, y por lo que me dan a entender los tutoriales que veo sobre estos temas, de una forma más o menos parecida, así es como funcionan este tipo de sistemas. Os comparto la clase y os explico como funciona.

    public sealed class MessageHelper
    {
        private static readonly MessageHelper instance = new MessageHelper();

        private Dictionary<object, object> messageCollector; 

        private MessageHelper()
        {
            messageCollector = new Dictionary<object, object>();
        }

        public static MessageHelper Instance
        {
            get
            {
                return instance;
            }
        }

        public void SendMessage<T>(T messageToRegister)
        {
            T aux = Activator.CreateInstance<T>();

            if (!messageCollector.Keys.Contains(aux.GetType()))
                messageCollector.Add(aux.GetType(), messageToRegister);
            else
                messageCollector[aux.GetType()] = messageToRegister;
        }

        public T ReceiveMessage<T>()
        {
            T aux = Activator.CreateInstance<T>();
            return (T)messageColector[aux.GetType()];
        }
    }

El primer punto destacable es que he implementado para la clase el patrón Singleton, y resulta obvio el motivo y además la misma está sellada para que no se pueda heredar.

Y lo único que he hecho en esta clase es crear dos métodos, uno de envío y otro de recepción de mensajes, que usan un diccionario de tipo clave=>valor para el almacenamiento y lectura de los mensajes. Para permitir que cualquier objeto pueda ser enviado y recibido como mensaje, he creado los métodos con un tipo genérico, lo que me da mucha libertad a la hora de usarla posteriormente.

¿Y cómo se usa esta clase?

Pues el funcionamiento es muy sencillo, como he dicho, podemos usar cualquier objeto para pasar el mensaje, aunque en mi caso estoy definiendo algunos objetos particulares con el mensaje que quiero pasar.

public class ExampleMessage
{
     public string MessageData;
     public int OtherMessageData;
}

Y lo usaríamos de la siguiente forma, he unido para el caso, las funciones de envío y recepción del mensaje, pero éstas, obviamente, irían en cada uno de los ViewModels que necesitáramos.

public void SendMessageFunction(string messageData, int otherMessageData)
{
    MessageHelper.Instance.SendMessage<ExampleMessage>(new ExampleMessage{ 
                                                  MessageData = messageData,
                                                  OtherMessageData = otherMessageData
                                              });
}

public void SendMessageFunction()
{
    string message = MessageHelper.Instance.ReceiveMessage<ExampleMessage>().MessageData;
    int other = MessageHelper.Instance.ReceiveMessage<ExampleMessage>().OtherMessageData;
}

Y nada más, espero que os ayude a comprender, si es que os era necesario, este tipo de sistemas. Yo como os decía, a veces para comprenderlos y comenzar a utilizarlos, necesito antes clases sencillas y hechas por mi en las que vea como funciona lo que estoy viendo en sistemas más complejos.

Un saludo y buen fin de semana a todos.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s