ObjectDataProvider – Parte I

Esta es la primera de dos partes de este tutorial, al final del mismo encontrán en enlace a la segunda parte.

Los definicón rápida "del libro" de ObjectDataProvider es que encapsula y expone un objeto para que pueda ser usado como una fuente de datos. En la práctica sigfnifica que pueden crear una clase, incluso usando constructores con parámetros, esa clase puede tener un miembro que devuelva un objeto List<>, y los datos de esa lista serán desplegados en cualquier control que soporte DataBinding con ObjectDataProvider. Realmente es muy útil y simplifica la reutilización de fuentes de datos, algo adicional es que tampién permite que los datos se mantengan sincronizados.

En el siguiente tutorial vamos a ver cómo enlazar datos entre una base de datos y un control Windows usando ObjectDataProviders y objetos del CLR.

Antes que nada, aclaro que para leer este tutorial deben tener conocimientos báscios de SqlConnection, referenciar proyectos, y conocer de forma general cómo se organizan los proyectos en Visual Studio y Blend.

Parte I: La Fuente de Datos.

Usaremos SQL Server para crear una tabla Personas con algunos campos como: Id, Nombre, Apellido.

Luego nos creamos un procedimiento almacenado llamado por ejemplo ObtenerPersonas que contendrá la sentencia SELECT Id, Nombre, Apellido FROM Personas.

Llenamos algunos datos de prueba y tenemos lista esta primera parte.

Parte II: La arquitectura de la aplicación.

  • Para este ejemplo organizaremos el código en los siguientes proyectos:
  • Para acceso datos (DAL – Biblioteca de clases)
  • Para transferencia de objectos (DTO – Biblioteca de clases)
  • Para la lógica del negocio (BLL – Biblioteca de clases)
  • Para la presentación (Interfaz de Usuario – Cliente Windows tipo WPF)

Algo bastante típico y común: En el proyecto para el DTO crearemos una clase llamada PersonaDto (usando el método clásico para las propiedades):

public class PersonaDto
{
 private int id;
 private string nombre;
 private string apellido;


 // Creamos de forma explícita un constructor predeterminado
 public PersonaDto()
 {
 }


 // Propiedades públicas para acceder a los campos
 public int Id 
 { 
    get { return id; }
    set { id = value; }
 }

 public string Nombre 
 { 
    get { return nombre; }
    set { nombre = value; }
 }
 
 public string Apellido 
 { 
    get { return apellido; }
    set { apellido = value; }
 }
}

Este será el objeto que pasaremos entre las capas y será una lista de esos objetos los que el ObjectDataProvider encapsulará.

Ahora tenemos que escribir el código para la Dal (PersonaDal) y Bll (PersonaBll) , para este tutorial no se mostrará el código ya que no es de gran importancia, además no tiene nada en especial, en la DAL nos conectamos a SQL Server y cagamos un DataSet o DataTable. En la BLL cramos un método para transformar el DataSet de la DAL a un objeto List<PersonaDto> y ya.

Antes de continuar, primero vamos a agregar algo adicional a nuestro proyecto Windows (PersonaWpf). En lugar de conectar un control Windows (por ejemplo un ListView) directamente con la clase PersonaPwf, vamos a crear un objeto intermedio que se encargará de gestionar algunos servicios para la interfaz del usuario:

  • Notificación de cambios en la fuente de datos.
  • Búsquedas de datos.

A esta clase intermedia la llamaremos PersonaBinding, y el código es el siguiente:

public class PersonaBinding : INotifyPropertyChanged
{
 List<PersonaDto> listaCompleta = new List<PersonaDto>();
 List<PersonaDto> vista = new List<PersonaDto>();
 string patronBusqueda;
 public PersonaBinding()
 {
   patronBusqueda = "";
 
   if (!DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
   {
     Refrescar();
   }
   else
   {
    // Crear item de prueba
    PersonaDto dummy = new PersonaDto();
    dummy.Id = 1;
    dummy.Nombre = "Juan";
    dummy.Codigo = "Perez";
    listaCompleta.Add(dummy);
   }
   Items = listaCompleta;
 }
 public List<PersonaDto> Items
   {
   get { return vista; }
   set { vista = value; OnPropertyChanged("Items"); }
   }
 public void Refrescar()
 {
  if (!DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
   listaCompleta = PersonaBll.ConsultarTodos();
 }
 public void Filtrar(string patron)
 {
  patronBusqueda = patron.ToLower();
  if (String.IsNullOrEmpty(patron))
   Items = listaCompleta;
  else
   Items = listaCompleta.FindAll(ContienePatron);
 }
 public bool ContienePatron(PersonaDto persona)
 {
  return (persona.Nombre.ToLower().Contains(patronBusqueda) || persona.Codigo.ToLower().Contains(patronBusqueda));
 }
 #region Miembros de INotifyPropertyChanged
 public event PropertyChangedEventHandler PropertyChanged;
 private void OnPropertyChanged(string propertyName)
 {
  if (this.PropertyChanged != null)
  {
   this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  }
 }
 #endregion
}

El código anterior hace algunas cosas interesantes:

  • Primero implementa la interfaz INotifyPropertyChanged que nos permite activar la notificación a los consumidore de datos (ej: ListView) de que se ha modificado la colección y reflejen los nuevos datos. Es importante ver que en el atributo Set de la propiedad Items, invoco al método OnPropertyChange que dispara el evento que notifica a los consumidores de datos.
  • Segundo, notamos que la clase mantiene dos Listas de datos, la una siempre contiene la colección completa y se usa internamente, la segunad (llamada vista) es la que le pasamos a los controles, y puede ser la lista completa de datos o los que cumplan con el método-predicado ContienePatron.
  • Tercero, antes de invocar al método de la Bll que consulta los datos, primero verificamos si la ventana está abierta en el diseñador, si está en el diseñador NO nos conectamos a la base y llenamos la lista con datos de ejemplo, caso contrario (cuando el programa está en ejecución) se conecta a la base. Esto es porque en tiempo de diseño Blend intenta compilar y ejeuctar este código y produciría un error al momento de tratar de  conectar con la base. En este artículo se explica el por qué de este error.

Compilamos nuestro proyecto para ver que todo esté bien y continuamos a la Parte II.

Una respuesta to “ObjectDataProvider – Parte I”

  1. […] ObjectDataProvider – Parte II (final) Esta es la segunda de dos partes de este tutorial, Este es el enlace a la primera parte. […]

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

A %d blogueros les gusta esto: