Empezando con Windows 7.1 (y XVIII) – Utilizando Behaviors


Los “comportamientos” (Behaviors) son piezas de funcionalidad relacionadas con la interacción del usuario y que pueden ser reutilizadas con facilidad.

Mucha gente asocia la utilización de un Behavior a Expression, y es más que lógica dicha asociación (échale un vistazo al link de referencia para ver dónde está clasificado dentro de la MSDN).

Sin embargo su utilización no se limita a Expression. Podemos sacarles partido en nuestro Windows Phone de manera sencila.

Montando Un Cuadro de Diálogo

Un escenario muy común en la utilización de cualquier patrón que busque desacoplar la capa de presentación de la lógica de presentación (es decir, la Vista de lo que sea que pongamos detrás) es mostrar un cuadro de diálogo. En su versión más sencilla, este cuadro muestra un mensaje de aviso al usuario y proporciona algún mecanismo para que el usuario escoga de entre un número limitado de acciones.

En este caso me voy a centrar en mostrar un mensaje de diálogo sencillo al usuario haciendo uso de un Behavior y de algunas facilidades que nos ofrece MVVM Light.

Al lío

Imagninemos que necesitamos realizar un intercambio de datos a través de la red y que no disponemos de conexión. Podríamos querer avisar al usuario de esta situación.

MVVM Light nos pone al alcance un tipo de mensaje llamado DialogMessage (desafortunadamente no es fácil encontrar documentación completa en la red sobre cada clase, afortunadamente ahí está el código para revisarlo).

Vamos a descomponer el problema en dos partes. Por un lado, necesitamos poder disponer de algún mecanismo declarativo que nos permita mostrar un cuadro de diálogo con título y texto variables (también sería bueno si pudiéramos mostrar diferentes acciones, pero eso me mete en un jardín en el que, por ahora, no quiero entrar).

Construir un Behavior para los Mensajes

Vamos a comenzar con la construcción de un Behavior que nos permita introducir declarativamente un cuadro de diálogo en la vista.

 1: using System;

 2: using System.Windows;

 3: using System.Windows.Interactivity;

 4: using GalaSoft.MvvmLight.Messaging;

 5:

 6: /// <summary>

 7: /// Clase que nos permitirá implementar un comportamiento para mostrar mensajes de forma ajustada al patrón MVVM

 8: /// </summary>

 9: public class DialogBehavior : Behavior<FrameworkElement>

 10: {

 11:     #region Miembros Públicos

 12:

 13:     public static DependencyProperty TituloProperty = DependencyProperty.Register("Titulo", typeof(string), typeof(DialogBehavior), new PropertyMetadata(String.Empty));

 14:     public static DependencyProperty IdentificadorProperty = DependencyProperty.Register("Identificador", typeof(string), typeof(DialogBehavior), new PropertyMetadata(String.Empty));

 15:     public static DependencyProperty TextoProperty = DependencyProperty.Register("Texto", typeof(string), typeof(DialogBehavior), new PropertyMetadata(String.Empty));

 16:

 17:     /// <summary>

 18:     /// Identificador

 19:     /// </summary>

 20:     public string Identificador

 21:     {

 22:         get

 23:         {

 24:             return (string)GetValue(IdentificadorProperty);

 25:         }

 26:         set

 27:         {

 28:             SetValue(IdentificadorProperty, value);

 29:         }

 30:     }

 31:

 32:     /// <summary>

 33:     /// Título a mostrar

 34:     /// </summary>

 35:     public string Titulo

 36:     {

 37:         get

 38:         {

 39:             return (string)GetValue(TituloProperty);

 40:         }

 41:         set

 42:         {

 43:             SetValue(TituloProperty, value);

 44:         }

 45:     }

 46:

 47:     //public string Titulo { get; set; }

 48:

 49:     /// <summary>

 50:     /// Texto a mostrar

 51:     /// </summary>

 52:     public string Texto

 53:     {

 54:         get

 55:         {

 56:             return (string)GetValue(TextoProperty);

 57:         }

 58:         set

 59:         {

 60:             SetValue(TextoProperty, value);

 61:         }

 62:     }

 63:

 64:     /// <summary>

 65:     /// Botones a mostrar

 66:     /// </summary>

 67:     public MessageBoxButton Botones { get; set; }

 68:

 69:     #endregion Miembros Públicos

 70:

 71:     #region Miembros Privados

 72:

 73:     private static Messenger _messenger = Messenger.Default;

 74:

 75:     /// <summary>

 76:     /// Método invocado para mostrar el mensaje

 77:     /// </summary>

 78:     /// <param name="dm"></param>

 79:     private void ShowDialog(GalaSoft.MvvmLight.Messaging.DialogMessage dm)

 80:     {

 81:         var result = MessageBox.Show(Texto, Titulo, Botones);

 82:

 83:         if (dm.Callback != null)

 84:             dm.Callback(result);

 85:     }

 86:

 87:     #endregion Miembros Privados

 88:

 89:     #region Miembros Protegidos

 90:

 91:     protected override void OnAttached()

 92:     {

 93:         base.OnAttached();

 94:

 95:         _messenger.Register<GalaSoft.MvvmLight.Messaging.DialogMessage>(this, Identificador, ShowDialog);

 96:     }

 97:

 98:     #endregion Miembros Protegidos

 99: }

De este código merede la pena destacar varias cosas.

  • Estamos heredando de la clase Behavior<FrameworkElement> que es el escenario más sencillo que podemos contemplar ahora mismo.
  • Hemos creado propiedades para el Identificador (ayuda a decidir sobre qué Diálogo estamos lanzando el mensaje), Título y Texto.
  • Como queremos que estas propiedades puedan estar enlazadas (ya sabes, DataBinding) con propiedades de la VistaModelo, hemos creado tres DependencyProperty por detrás que nos ayudarán en el soporte al DataBinding (si me limito a exponer las propiedades de Texto no es posible establecer el mencionado DataBinding)
  • Por lo demás, no mucho más. Lanzamos un MessageBox y llamamos a la función de callback (si la hay) con el resultado de la elección del usuario.

Ahora la vista

Con nuestro Behavior creado, nos vamos a la vista a declararlo.

 1: <i:Interaction.Behaviors>

 2:     <jdmv:DialogBehavior

 3:         Titulo="{Binding Path=TituloDialogo}"

 4:         Texto="{Binding Path=TextoDialogo}"

 5:         Botones="OKCancel"

 6:         Identificador="{Binding Path=IdMensajeMensaje}" />

 7: </i:Interaction.Behaviors>

Los espacios de nombres utilizados son los siguientes (he quitado unos cuantos para facilitar la lectura).

 1: <phone:PhoneApplicationPage

 2:     x:Class="Lcdad.SquareMatrix.ViewModel.FourSquareLogin"

 3:     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

 4:     xmlns:jdmv="clr-namespace:Jdmveira.WindowsPhone.Mvvm.Messaging;assembly=Jdmveira.WindowsPhone">

No hay mucho que comentar. Las propiedades están enlazadas con propiedades de la VistaModelo.

Por último, la VistaModelo

Tan solo nos queda la VistaModelo, en ella he centralizado la utilización de los mensajes y los errores a través de dos métodos. Pongo el detalle de Mensaje por ser el más completo.

 1: /// <summary>

 2: /// Muestra un mensaje con opciones en pantalla

 3: /// </summary>

 4: /// <param name="titulo">Título del diálogo de error</param>

 5: /// <param name="texto">Texto a mostrar</param>

 6: /// <param name="callback">Instancia de <see cref="Action<MessageBoxResult>"/> con el método de callback para manejar la respuesta de usuario</param>

 7: private void Mensaje(string titulo, string texto, Action<MessageBoxResult> callback)

 8: {

 9:     TituloDialogo = titulo;

 10:     TextoDialogo = texto;

 11:

 12:     var msg = new DialogMessage(this, this, texto, callback);

 13:

 14:     DispatcherHelper.CheckBeginInvokeOnUI(() => { MessengerInstance.Send<DialogMessage>(msg, IdMensajeMensaje); });

 15: }

Que recibe los argumentos y se asegura de lanzar el cuadro de diálogo en el contexto del hilo de la UI.

Como podéis ver, su utilización es muy sencilla y permite desacoplar la operativa de mostrar el mensaje en pantalla. Hay todavía espacio para mejorarlo, pero es un buen comienzo.

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