Archivo de la etiqueta: C#

Comunicar Formularios usando Easy.MessageHub

Easy.MessageHub es un framework que por dentro viene implementado el patrón Event Aggregator, que justamente basandose en eventos permite una comunicación desacoplada entre formularios sin relación directa en nuestra aplicación.

EventAggregator: Por el nombre es fácil decir que los agregados de eventos un Publisher/Subscriber trabajan con EventAggregator como un centro cuya tarea consiste en agregar todos los mensajes publicados y enviar el mensaje a los suscriptores interesados.

EventAggregator

Antes de comenzar hay que instalar Easy.MessageHub ejecutar el siguiente comando en la consola de administación de paquetes.

Install-Package Easy.MessageHub

Una vez instalado pasamos a crear una clase como contrato para dichos eventos.

public class VariableSelected
     {
         public int Codigo { get; set; }
         public string StrValor { get; set; }
     }

Desde el formulario hijo implementamos MessageHub

public partial class FrmBusqueda : Form
     {
        
         private readonly IMessageHub _eventHub;
         public FrmBusqueda(string title, EnumAsignacionTablas t)
         {
             _titulo = title;
             _table = t;
             CompleteEvent.Complete += CompleteEvent_Complete;
             InitializeComponent();
         }

        public FrmBusqueda(string title, EnumAsignacionTablas t, IMessageHub evenHub) : this(title, t)
         {
             _eventHub = evenHub;
         }

private void ObtenerId()
         {
             if (dgvBusqueda.Rows.Count > 0)
             {
                 if (dgvBusqueda.CurrentRow != null)
                 {
                     _idRow = Convert.ToInt32(dgvBusqueda.CurrentRow.Cells[0].Value);
                     _desRow = Convert.ToString(dgvBusqueda.CurrentRow.Cells[1].Value);
                 }
                 _eventHub.Publish(new VariableSelected {Codigo = _idRow, StrValor = _desRow});
             }
         }

El padre recibe los datos y los procesa

private void btnBuscarColor_Click(object sender, EventArgs e)
         {
             var argNombreEntidad = new ConstructorArgument(“title”, StrColour.NameEntity);
             var argT = new ConstructorArgument(“t”, EnumAsignacionTablas.Colour);
             var frm = CompositionRoot.Resolve<FrmBusqueda>(argNombreEntidad, argT); 
             _eventHub.Subscribe<VariableSelected>(OnColorSelected);
             frm.ShowDialog();
         }

        private void OnColorSelected(VariableSelected colorEvent)
         {
             if (colorEvent.Codigo != 0 && !string.IsNullOrEmpty(colorEvent.StrValor))
             {
                 if (DetalleItemColour.Count != 1)
                 {
                     var entity = new Colour()
                     {
                         ColourId = colorEvent.Codigo,
                         Nombre = colorEvent.StrValor
                     };
                     _detalleColour.Add(entity);
                     dgvColor.AutoGenerateColumns = false;
                     dgvColor.DataSource = DetalleItemColour;
                    
                     //De suscribir
                     _eventHub.ClearSubscriptions();
                 }
                 else
                 {
                     MessageBoxEx.EnableGlass = false;
                     MessageBoxEx.Show(this, “Solo se permite un solo Color”, StrColour.NameEntity,
                         MessageBoxButtons.OK, MessageBoxIcon.Information);
                     vBool = false;
                     colorEvent.Codigo = 0;
                     colorEvent.StrValor = String.Empty;
                 }
             }
         }

PropertyGrid

Hace poco conocí este control, por que me mandaron en mi trabajo a implementarlo en el desarrollo de una aplicación que estaba haciendo y bueno no encontré mucha información, me puse a investigar y logre utilizarlo, les mostrare como implementarlo.

PropertyGrid

PropertyGrid, es el mismo control que se usa para ver las propiedades de un control en el IDE de VS.NET, muestra las propiedades de cualquier objeto o tipo, y recupera las propiedades del elemento, principalmente mediante la reflexión. (La reflexión es una tecnología que proporciona información de tipo en tiempo de ejecución). El control PropertyGrid se compone de dos columnas y, como mínimo, tantas filas como propiedades editables contiene el objeto. La columna de la izquierda identifica la propiedad por su nombre, y la de la derecha ofrece un espacio para ver y/o editar la propiedad. Es muy útil para el uso del usuario final que le permite editar las propiedades de un objeto,  lo cual, sin duda, añade elegancia y valor a la aplicación. Sin mas preámbulo manos a la obra.

Se utiliza una clase para establecer las propiedades del objeto, algo muy importante hay que declarar el namespace ComponentModel, de la siguiente manera using System.ComponentModel.

public class Producto
    {
        // Se implementan los enum para poder cargar los combobox
        public enum Colors
        {
            AZUL = 1,
            VERDE = 2,
            AMARILLO = 3
        }

        public enum Medida
        {
            SMALL = 1,
            MEDIUM = 2,
            LARGE = 3
        }

        [Category("Producto"), DescriptionAttribute("Código del producto")]
        public string Código { get; set; }

        [Category("Producto"), DescriptionAttribute("Color que tiene el producto")]
        public Colors Color { get; set; }

        [Category("Producto"), DescriptionAttribute("Tamaño, medida"), TypeConverter(typeof(ConvertTalla))]
        public string Talla { get; set; }

        [Category("Producto"), DescriptionAttribute("Modelo del cuello")]
        public string Cuello { get; set; }

        [Category("Producto"), DescriptionAttribute("Indica si se encuentra activo")]
        public bool Estado { get; set; }

    }

Ahora vamos al load del formulario para instanciar la clase producto para asignársela al control PropertyGrid.

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Instanciamos la clase Producto
            Producto producto = new Producto();
            
            // Le pasamos la instancia al objeto
            propertyGrid1.SelectedObject = producto; 
        }
    }

Ahora les paso a explicar de los atributos que se aplicaron a la propiedades de la clase producto, estos atributos se pueden usar gracias al namespace que declaramos en la clase. Los atributos son etiquetas declarativas que se aplican a la propiedades que se pueden recuperar en tiempo de ejecución mediante la reflexión.

  • DescriptionAttribute . Establece el texto de la propiedad que se muestra en el panel de ayuda siguiente descripción de las propiedades. Esta es una manera útil para proporcionar texto de ayuda de la propiedad activa (la propiedad que tiene el foco).
  • CategoryAttribute . Establece la categoría que la propiedad se encuentra en la red. Esto es útil cuando se desea una propiedad agrupados por un nombre de categoría. Al Misc categoría. Aplique este atributo a todas las propiedades.
  • BrowsableAttribute – Indica si la propiedad se muestra en la cuadrícula. Esto es útil cuando se quiere ocultar una propiedad de la red. De forma predeterminada,
  • ReadOnlyAttribute – Indica si la propiedad es de sólo lectura. Esto es útil cuando se desea mantener la propiedad de ser editable en la red. De forma predeterminada, una propiedad pública con obtener y establecer funciones de acceso se puede editar en la cuadrícula.
  • DefaultValueAttribute – Identifica el valor predeterminado de la propiedad. Esto es útil cuando se desea proporcionar un valor predeterminado para una propiedad y luego determinar si el valor de la propiedad es diferente al predeterminado. Aplique este atributo a todas las propiedades.
  • DefaultPropertyAttribute – Identifica la propiedad predeterminada de la clase. La propiedad predeterminada de una clase obtiene el foco por primera vez cuando se selecciona la clase en la cuadrícula.

Segunda parte Acceso a Datos

Ahora la talla que se carga con el enum Medida, lo cargamos con datos reales que están en la Base de datos, para eso vamos a comentar el enum Medida que esta en la Clase Producto, hacemos la consulta SQL contra la base de datos, de la siguiente manera.

public class TallaRepository
    {
        public static List<tallaentity> GetTalla()
        {
            using(SqlCeConnection cn = Conexion.Conectar("PruebaConnectionString"))
            {
                cn.Open();
                using(SqlCeCommand cmd = cn.CreateCommand())
                {
                    cmd.CommandText = "SELECT idTalla, descripcion FROM Tallas";
                    List<tallaentity> talla = new List<tallaentity>();
                    using(SqlCeDataReader reader = cmd.ExecuteReader())
                    {
                        while(reader.Read())
                        {
                            TallaEntity t = new TallaEntity()
                                {
                                    idTalla = Convert.ToInt32(reader["idTalla"]),
                                    descripcion = Convert.ToString(reader["descripcion"])
                                };
                            talla.Add(t);
                        }
                    }
                    return talla;
                }
            }
        }

Ahora vamos a crear una clase donde se le asigna los datos al ComboBox a través de una lista y en donde se le asigna propiedades.

internal class ConvertTalla : StringConverter
    {
        // Permite alternar dinámicamente entre el ComboBox, donde el usuario debe elegir entre 
        // las opciones disponible, y TextBox, donde el usuario introduce libremente un valor.
        public override bool
           GetStandardValuesSupported(
           ITypeDescriptorContext context)
        {
            //True - means show a Combobox
            //and False for show a Modal 
            return true;
        }

        // Determina si el usuario debe limitarse a los valores de la lista o si, aun disponiendo de ella,
        // Puede introducir un valor nuevo.
        public override bool
            GetStandardValuesExclusive(
            ITypeDescriptorContext context)
        {
            //False - a option to edit values 
            //and True - set values to state readonly
            return true;
        }

        // Entrega la lista de miembros del ComboBox.
        public override StandardValuesCollection
           GetStandardValues(
           ITypeDescriptorContext context)
        {
            List<tallaentity> lista = TallaRepository.GetTalla(); 
            return new StandardValuesCollection(lista.Select(x =&gt; x.descripcion).ToArray());

        }
    }

Ahora solo nos toca modificar la propiedad de la Clase Producto

[Category("Producto"), DescriptionAttribute("Tamaño, medida"), TypeConverter(typeof(ConvertTalla))]
        public string Talla { get; set; }

Esta clase reimplementa tres funciones:

GetStandardValuesSupported permite alternar dinámicamente entre el ComboBox, donde el usuario debe elegir entre las opciones disponibles, y el TextBox, donde el usuario introduce libremente un valor.

GetStandardValuesExclusive determina si el usuario debe limitarse a los valores de la lista o si, aun disponiendo de ella, puede introducir un valor nuevo.

GetStandardValues entrega la lista de miembros del Combobox.

Proyecto C#

NOTA : El proyecto esta desarrollado en VS 2012 y se esta usando SQL CE 4.0 la base de datos ya viene incrustada en el proyecto, solo tienen que correr la aplicación.