Continuando con la serie acerca de la implementación del patrón arquitectural Model-View-ViewModel y en específico utilizando la herramienta MVVM Light Toolkit, este artículo dará por concluida la serie, con la implementación del ViewModel para Empleados y su correspondiente View.

Algunos seguidores del blog han sugerido nuevos ejemplos con algunas variantes y con la finalidad de visualizar las diferentes aristas que puede tener la implementación del patrón en conjunto con ADO.NET Entity Framework, lo cual estaré haciendo con mucho gusto en siguientes artículos.

Procedemos entonces a crear el ViewModel para Empleado, ubicados en el proyecto Empleados.WPF y en la carpeta ViewModel, damos clic derecho para agregar un nuevo ítem.

EmpleadoViewModel

podemos eliminar los comentarios que se crean por omisión, agreguemos los siguientes namespaces System.Collections.ObjectModel, Empleados.WPF.Model, System.Collections.Generic y continuamos con la creación de las propiedades necesarias que estarán enlazadas al View, creamos una #region ViewModel Properties y dentro de esta otra #region ViewModel Property : ListaEmpleados , utilizando el snippet mvvminpc creamos una propiedad de tipo ObservableCollection<EmpleadoModel> que se llame ListaEmpleados.

  1. #region ViewModel Property : ListaEmpleados
  2.  
  3.         /// <summary>
  4.         /// The <see cref="ListaEmpleados" /> property's name.
  5.         /// </summary>
  6.         public const string ListaEmpleadosPropertyName = "ListaEmpleados";
  7.  
  8.         private ObservableCollection<EmpleadoModel> _listaEmpleados;
  9.  
  10.         public ObservableCollection<EmpleadoModel> ListaEmpleados
  11.         {
  12.             get
  13.             {
  14.                 return _listaEmpleados;
  15.             }
  16.  
  17.             set
  18.             {
  19.                 if (_listaEmpleados == value) return;
  20.  
  21.                 _listaEmpleados = value;
  22.  
  23.                 // Update bindings, no broadcast
  24.                 RaisePropertyChanged(ListaEmpleadosPropertyName);
  25.             }
  26.         }
  27.  
  28.         #endregion

 

La siguiente propiedad a incluir es CurrentEmpleado, creamos una #region ViewModel Property : CurrentEmpleado y dentro de esta una propiedad de tipo EmpleadoModel

  1. #region ViewModel Property : CurrentEmpleado
  2.  
  3.         /// <summary>
  4.         /// The <see cref="CurrentEmpleado" /> property's name.
  5.         /// </summary>
  6.         public const string CurrentEmpleadoPropertyName = "CurrentEmpleado";
  7.  
  8.         private EmpleadoModel _currentEmpleado;
  9.  
  10.         public EmpleadoModel CurrentEmpleado
  11.         {
  12.             get
  13.             {
  14.                 return _currentEmpleado;
  15.             }
  16.  
  17.             set
  18.             {
  19.                 if (_currentEmpleado == value) return;
  20.  
  21.                 _currentEmpleado = value;
  22.  
  23.                 // Update bindings, no broadcast
  24.                 RaisePropertyChanged(CurrentEmpleadoPropertyName);
  25.             }
  26.         }
  27.  
  28.         #endregion

 

La siguiente propiedad nos permitirá desplegar en el View los puestos registrados en la base de datos y a su vez enlazar el puesto seleccionado a un empleado. Se crea otra #region ViewModel Property : ListaPuestos y se crea una propiedad de tipo List<PuestoModel> llamada ListaPuestos

  1. #region ViewModel Property : ListaPuestos
  2.  
  3.         /// <summary>
  4.         /// The <see cref="ListaPuestos" /> property's name.
  5.         /// </summary>
  6.         public const string ListaPuestosPropertyName = "ListaPuestos";
  7.  
  8.         private List<PuestoModel> _listaPuestos;
  9.  
  10.         public List<PuestoModel> ListaPuestos
  11.         {
  12.             get
  13.             {
  14.                 return _listaPuestos;
  15.             }
  16.  
  17.             set
  18.             {
  19.                 if (_listaPuestos == value) return;
  20.  
  21.                 _listaPuestos = value;
  22.  
  23.                 // Update bindings, no broadcast
  24.                 RaisePropertyChanged(ListaPuestosPropertyName);
  25.             }
  26.         }
  27.  
  28.         #endregion

 

Continuamos con los comandos, agregamos el siguiente namespace Galasoft.MvvmLight.Command  y creamos una #region ViewModel Commands y dentro de esta los comandos necesarios para manejar los botones del View y la selección en un Grid.

  1. #region ViewModel Commands
  2.  
  3.         public RelayCommand NewCommand { get; set; }
  4.         public RelayCommand SaveCommand { get; set; }
  5.         public RelayCommand DeleteCommand { get; set; }
  6.         public RelayCommand<EmpleadoModel> SelectionChangedCommand { get; set; }
  7.  
  8.         #endregion

 

Luego una nueva #region ViewModel Public Methods y dentro de esta incluimos el método constructor de la clase, en el constructor cargamos la lista de todos los empleados que haya en la base de datos en la propiedad de tipo ObservableCollection ListaEmpleados, cargamos todos los puestos así como la inicialización de los RelayCommand.

  1. /// <summary>
  2.         /// Initializes a new instance of the EmpleadoViewModel class.
  3.         /// </summary>
  4.         public EmpleadoViewModel()
  5.         {
  6.             ListaEmpleados = new ObservableCollection<EmpleadoModel>(EmpleadoModel.GetAllEmpleados());
  7.             ListaPuestos   = new List<PuestoModel>(PuestoModel.GetAllPuestos());
  8.             RegisterCommands();
  9.             New();
  10.         }

 

Lo que sigue es la creación de los métodos necesarios para que los comandos “RelayCommand” funcionen adecuadamente. Métodos New, Save, CanSave, Delete, CanDelete.

  1. public void New()
  2.         {
  3.             CurrentEmpleado = new EmpleadoModel();
  4.         }
  5.  
  6.         public void Save()
  7.         {
  8.             if (CurrentEmpleado.IdEmpleado == 0)
  9.             {
  10.                 CurrentEmpleado.IdEmpleado = EmpleadoModel.InsertEmpleado(CurrentEmpleado);
  11.                 ListaEmpleados.Add(CurrentEmpleado);
  12.             }
  13.             else
  14.             {
  15.                 EmpleadoModel.UpdateEmpleado(CurrentEmpleado);
  16.             }
  17.             New();
  18.         }
  19.  
  20.         public bool CanSave()
  21.         {
  22.             return !string.IsNullOrEmpty(CurrentEmpleado.Identificacion) &&
  23.                    !string.IsNullOrEmpty(CurrentEmpleado.Nombre) &&
  24.                    !string.IsNullOrEmpty(CurrentEmpleado.PrimerApellido) &&
  25.                    !string.IsNullOrEmpty(CurrentEmpleado.Genero) &&
  26.                    CurrentEmpleado.Puesto != null;
  27.         }
  28.  
  29.         public void Delete()
  30.         {
  31.             EmpleadoModel.DeleteEmpleado(CurrentEmpleado.IdEmpleado);
  32.             ListaEmpleados.Remove(CurrentEmpleado);
  33.             New();
  34.         }
  35.  
  36.         public bool CanDelete()
  37.         {
  38.             return CurrentEmpleado.IdEmpleado != 0;
  39.         }

 

procedemos a la inicialización de los comandos “RelayCommand” previamente declarados, creamos una #region ViewModel Private Methods y dentro de esta el método RegisterCommands

  1. #region ViewModel Private Methods
  2.  
  3.         private void RegisterCommands()
  4.         {
  5.             NewCommand = new RelayCommand(New);
  6.             SaveCommand = new RelayCommand(Save, CanSave);
  7.             DeleteCommand = new RelayCommand(Delete, CanDelete);
  8.             SelectionChangedCommand = new RelayCommand<EmpleadoModel>(empleado =>
  9.             {
  10.                 if (empleado == null) return;
  11.                 CurrentEmpleado = empleado;
  12.             });
  13.         }
  14.  
  15.         #endregion

Con esto concluímos el ViewModel de Empleados y como se puede apreciar a diferencia del ViewModel de Puesto, no se crearon propiedades individuales para enlazar a cada uno de los campos de captura de datos en el View como si se hizo con la descripción del Puesto, si no, que se está utilizando el objeto de tipo EmpleadoModel en este caso CurrentEmpleado, que a su vez cada una de sus propiedades implementa la interfaz INotifyPropertyChanged, para realizar la labor de DataBinding entre el ViewModel y el View como se verá a continuación con la creación del View, pero antes asegurémonos que el View podrá acceder el ViewModel por medio del ViewModelLocator.

Accedemos a ViewModelLocator.cs y creamos una nueva #region Empleado ViewModel seguidamente de la region Puesto ViewModel. Dentro de esta región utilizamos el snippet mvvmlocatorproperty que provee el MVVM Light Toolkit y una vez implementado el locator para EmpleadoViewModel realizamos un procedimiento similar al anterior locator para PuestoViewModel con el método Cleanup(), eliminando el creado por omisión pero dejando el llamado a ClearEmpleadoViewModel() en el otro método Cleanup() que ya se tenía como se ve a continuación.

  1. #region Empleado ViewModel
  2.  
  3.         private static EmpleadoViewModel _empleadoViewModel;
  4.  
  5.         /// <summary>
  6.         /// Gets the EmpleadoViewModel property.
  7.         /// </summary>
  8.         public static EmpleadoViewModel EmpleadoViewModelStatic
  9.         {
  10.             get
  11.             {
  12.                 if (_empleadoViewModel == null)
  13.                 {
  14.                     CreateEmpleadoViewModel();
  15.                 }
  16.  
  17.                 return _empleadoViewModel;
  18.             }
  19.         }
  20.  
  21.         /// <summary>
  22.         /// Gets the EmpleadoViewModel property.
  23.         /// </summary>
  24.         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
  25.             "CA1822:MarkMembersAsStatic",
  26.             Justification = "This non-static member is needed for data binding purposes.")]
  27.         public EmpleadoViewModel EmpleadoViewModel
  28.         {
  29.             get
  30.             {
  31.                 return EmpleadoViewModelStatic;
  32.             }
  33.         }
  34.  
  35.         /// <summary>
  36.         /// Provides a deterministic way to delete the EmpleadoViewModel property.
  37.         /// </summary>
  38.         public static void ClearEmpleadoViewModel()
  39.         {
  40.             _empleadoViewModel.Cleanup();
  41.             _empleadoViewModel = null;
  42.         }
  43.  
  44.         /// <summary>
  45.         /// Provides a deterministic way to create the EmpleadoViewModel property.
  46.         /// </summary>
  47.         public static void CreateEmpleadoViewModel()
  48.         {
  49.             if (_empleadoViewModel == null)
  50.             {
  51.                 _empleadoViewModel = new EmpleadoViewModel();
  52.             }
  53.         }
  54.  
  55.         #endregion

 

  1. /// <summary>
  2.         /// Cleans up all the resources.
  3.         /// </summary>
  4.         ///
  5.         public static void Cleanup()
  6.         {
  7.             ClearMain();
  8.             ClearEmpleadoViewModel();
  9.             //ClearPuestoViewModel();
  10.         }

 

Nótese el comentario en //ClearPuestoViewModel() en la imagen anterior, esto se debe a que no vamos a ejecutar la pantalla PuestoView, que a su vez por medio del locator crea una instancia de PuestoViewModel, si no que lo haremos solamente para el View de Empleado.

En este último artículo de la serie, voy a introducir algunos conceptos de WPF, crear una interfaz de usuario un poco más agradable y así aprovechar el tutorial para explorar el tema de controles de usuario, por que no sería lógico tener que estar creando la misma botonera (botones de Nuevo, Guardar, Eliminar, etc.) para cada programa de mantenimiento que vayamos a crear.

Ubicados en el Proyecto Empleados.WPF damos clic derecho, Add/New/Folder, le asignamos el nombre images, y dentro de este folder colocamos las imágenes que tendrán nuestros botones http://bit.ly/mWJzY9 , una vez descargadas y ubicados en el folder recién creado, damos clic derecho Add/Existing Item… para seleccionar las imágenes

Crearemos algunos estilos para darle a nuestra interfaz de usuario un aspecto diferente y moderno, algunos de estos estilos serán generales para toda la aplicación, por lo cual estarán ubicados en el App.xaml y otros estilos serán locales para uso únicamente del View ó control donde se definan. Accedemos al archivo App.xaml y dentro de la etiqueta <Application.Resources> incluimos lo siguiente:

  1. Application.Resources>
  2.         <!–Global View Model Locator–>
  3.         <vm:ViewModelLocator x:Key="Locator"
  4.                              d:IsDataSource="True" />
  5.  
  6.         <LinearGradientBrush
  7.             x:Key="BottomBorderBackground"
  8.             EndPoint="0.5,1"
  9.             StartPoint="0.5,0">
  10.             <GradientStop Color="#FF96BFCD" Offset="0" />
  11.             <GradientStop Color="#FF4A7681" Offset="1" />
  12.         </LinearGradientBrush>
  13.  
  14.         <LinearGradientBrush
  15.             x:Key="InnerBorderBackground"
  16.             EndPoint="0.5,1"
  17.             StartPoint="0.5,0">
  18.             <GradientStop Color="#FFF3F3F3" Offset="0" />
  19.             <GradientStop Color="#FFF3F3F3" Offset="1" />
  20.             <GradientStop Color="#FFE0E0E0" Offset="0.45" />
  21.         </LinearGradientBrush>
  22.  
  23.     </Application.Resources>

 

Vamos a crear el control de usuario que nos permitirá colocar los botones que tendrán nuestros programas de mantenimiento, ubicados en el proyecto Empleados.WPF damos clic derecho, Add/New/Folder, le asignamos el nombre controles y ubicados en este folder damos nuevamente clic derecho Add/User Control…, le asignamos el nombre BotonesControl.xaml , ajustamos los valores de d:Designheight=”50” y d:DesignWith=”600” en el código xaml y antes de la declaración de la etiqueta <Grid> que se crea por omisión incluimos la etiqueta <UserControl.Resources> dentro de esta etiqueta se incluirán algunos estilos de uso local, solamente para este control de usuario.

  1. <UserControl.Resources>
  2.         <Style
  3.             x:Key="myLabelStyle"
  4.             TargetType="{x:Type Label}">
  5.             <Setter Property="Foreground" Value="White" />
  6.             <Setter Property="FontSize" Value="10" />
  7.             <Setter Property="Margin" Value="0,-5,0,0" />
  8.         </Style>
  9.         <Style
  10.             x:Key="myImageStyle"
  11.             TargetType="{x:Type Image}">
  12.             <Setter Property="Width" Value="26" />
  13.             <Setter Property="Height" Value="26" />
  14.             <Setter Property="Margin" Value="0,3,0,0" />
  15.         </Style>
  16.         <Style
  17.             x:Key="myButtonStyle"
  18.             TargetType="{x:Type Button}">
  19.             <Setter Property="BorderBrush" Value="Transparent" />
  20.             <Setter Property="Background" Value="Transparent"/>
  21.             <Setter Property="Cursor" Value="Hand"/>
  22.         </Style>
  23.         <Style
  24.             x:Key="myStackPanelStyle"
  25.             TargetType="StackPanel">
  26.             <Setter Property="Background" Value="Transparent"/>
  27.             <Setter Property="Margin" Value="2,0" />
  28.         </Style>
  29.     </UserControl.Resources>

 

Luego a la etiqueta <Grid> le agregamos los siguientes valores

  1. <Grid
  2.         VerticalAlignment="Top"
  3.         HorizontalAlignment="Stretch"
  4.         Height="50">
  5.         <Grid.Background>
  6.             <LinearGradientBrush
  7.                 EndPoint="0.5,1"
  8.                 StartPoint="0.5,0">
  9.                 <GradientStop Color="#FF999999" Offset="0" />
  10.                 <GradientStop Color="#FF142533" Offset="1" />
  11.                 <GradientStop Color="#FF3F3F3F" Offset="0.5" />
  12.                 <GradientStop Color="#FF0D161D" Offset="0.5" />
  13.             </LinearGradientBrush>
  14.         </Grid.Background>
  15.     </Grid>

 

Siempre dentro de la etiqueta <Grid> y después de la declaración de </Grid.Background> vamos a crear los botones de nuestro control, pero antes debemos crear el contenedor donde estarán los botones, para eso creamos un <StackPanel Orientation=”Horizontal”> y dentro del StackPanel los botones:

  1. <Grid
  2.         VerticalAlignment="Top"
  3.         HorizontalAlignment="Stretch"
  4.         Height="50">
  5.         <Grid.Background>
  6.             <LinearGradientBrush
  7.                 EndPoint="0.5,1"
  8.                 StartPoint="0.5,0">
  9.                 <GradientStop Color="#FF999999" Offset="0" />
  10.                 <GradientStop Color="#FF142533" Offset="1" />
  11.                 <GradientStop Color="#FF3F3F3F" Offset="0.5" />
  12.                 <GradientStop Color="#FF0D161D" Offset="0.5" />
  13.             </LinearGradientBrush>
  14.         </Grid.Background>
  15.         <StackPanel Orientation="Horizontal">
  16.             <Button
  17.                 Style="{StaticResource myButtonStyle}"
  18.                 Command="{Binding NewCommand, Mode=OneWay}">
  19.                 <StackPanel Style="{StaticResource myStackPanelStyle}">
  20.                     <Image Source="/images/New.png" Style="{StaticResource myImageStyle}" />
  21.                     <Label Content="Nuevo" Style="{StaticResource myLabelStyle}" />
  22.                 </StackPanel>
  23.             </Button>
  24.             <Button
  25.                 Style="{StaticResource myButtonStyle}"
  26.                 Command="{Binding SaveCommand, Mode=OneWay}">
  27.                 <StackPanel Style="{StaticResource myStackPanelStyle}">
  28.                     <Image Source="/images/Save.png" Style="{StaticResource myImageStyle}" />
  29.                     <Label Content="Grabar" Style="{StaticResource myLabelStyle}" />
  30.                 </StackPanel>
  31.             </Button>
  32.             <Button
  33.                 Style="{StaticResource myButtonStyle}"
  34.                 Command="{Binding DeleteCommand, Mode=OneWay}">
  35.                 <StackPanel Style="{StaticResource myStackPanelStyle}">
  36.                     <Image Source="/images/Delete.png" Style="{StaticResource myImageStyle}" />
  37.                     <Label Content="Borrar" Style="{StaticResource myLabelStyle}" />
  38.                 </StackPanel>
  39.             </Button>
  40.             <Button
  41.                 Style="{StaticResource myButtonStyle}"
  42.                 Command="{Binding SearchCommand, Mode=OneWay}">
  43.                 <StackPanel Style="{StaticResource myStackPanelStyle}">
  44.                     <Image Source="/images/Search.png" Style="{StaticResource myImageStyle}" />
  45.                     <Label Content="Buscar" Style="{StaticResource myLabelStyle}" />
  46.                 </StackPanel>
  47.             </Button>
  48.             <Button
  49.                 Style="{StaticResource myButtonStyle}"
  50.                 Command="{Binding RefreshCommand, Mode=OneWay}">
  51.                 <StackPanel Style="{StaticResource myStackPanelStyle}">
  52.                     <Image Source="/images/Refresh.png" Style="{StaticResource myImageStyle}" />
  53.                     <Label Content="Refrescar" Style="{StaticResource myLabelStyle}" />
  54.                 </StackPanel>
  55.             </Button>
  56.         </StackPanel>
  57.     </Grid>

 

Como se puede apreciar, para cada botón hemos establecido la propiedad Command que se estará enlazando en el ViewModel con los RelayCommand creados anteriormente y hemos optimizado el código xaml con los estilos creados anteriormente en la sección <UserControl.Resources> a fin de reutilizarlos y no tener que escribir las mismas propiedades para cada uno de los botones. Al final nuestro control de usuario debería verse de la siguiente forma:

ButtonControl

Compilamos el Proyecto, así nos aseguramos que todo vaya bien, y siempre ubicados siempre en el Proyecto Empleados.WPF y en la carpeta View, damos clic derecho y Add New Item para crear la Vista EmpleadosView.xaml

EmpleadoView

una vez creada la pantalla, en el código XAML ingresamos los valores de d:DesignWidth=”600” y d:DesignHeight=”640”, ingresamos la propiedad WindowsStartupLocation=”CenterScreen”, Title=”Gestión de Empleados” y DataContext=”{Binding EmpleadoViewModel, Source={StaticResource Locator}}” y el namespace xmlns:usrControl=”clr-namespace:Empleados.Wpf.controles”, luego agregamos al <Grid> la definición de 2 Rows y seguidamente al cierre de la definición de los Rows, agregamos el user Control de los botones colocando lo siguiente: <usrControl:BotonesControl Grid.Row=”0”> , Luego creamos un par de controles de tipo <Border>, uno dentro del otro, hasta ahora el código xaml debería verse así:

  1. <Window x:Class="Empleados.WPF.View.EmpleadoView"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         mc:Ignorable="d"
  7.         d:DesignWidth="600"
  8.         d:DesignHeight="640"
  9.         WindowStartupLocation="CenterScreen"
  10.         Width="600"
  11.         Height="640"
  12.         DataContext="{Binding EmpleadoViewModel, Source={StaticResource Locator}}"
  13.         Title="Gesti?n de Empleados"
  14.         xmlns:usrControl="clr-namespace:Empleados.WPF.controles">
  15.     <Grid>
  16.         <Grid.RowDefinitions>
  17.             <RowDefinition Height="50" />
  18.             <RowDefinition />
  19.         </Grid.RowDefinitions>
  20.         <usrControl:BotonesControl
  21.             Grid.Row="0" />
  22.         <Border
  23.             Grid.Row="1"
  24.             Background="{StaticResource BottomBorderBackground}">
  25.             <Border
  26.                 Margin="10,8,10,10"
  27.                 CornerRadius="4"
  28.                 Background="{StaticResource InnerBorderBackground}">
  29.                 
  30.             </Border>
  31.         </Border>
  32.     </Grid>
  33. </Window>

 

Dentro del último <Border> agregamos un <Grid> y dentro de este lo siguiente es colocar los controles necesarios para la captura de información del mantenimiento de empleados, agregamos los siguientes namespaces al código xaml xmlns:i=”http://schemas.microsoft.com/expression/2010/interactivity”  y  xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"

  1. <Grid>
  2.                     <TextBlock
  3.                         Height="23"
  4.                         HorizontalAlignment="Left"
  5.                         Margin="21,23,0,0"
  6.                         Text="Identificaci?n"
  7.                         VerticalAlignment="Top" />
  8.                     <TextBox
  9.                         Height="23"
  10.                         HorizontalAlignment="Left"
  11.                         Margin="122,20,0,0"
  12.                         Text="{Binding Path=CurrentEmpleado.Identificacion, UpdateSourceTrigger=PropertyChanged}"
  13.                         VerticalAlignment="Top"
  14.                         Width="173" />
  15.                     <TextBlock
  16.                         Height="23"
  17.                         HorizontalAlignment="Left"
  18.                         Margin="21,52,0,0"
  19.                         Text="Nombre"
  20.                         VerticalAlignment="Top" />
  21.                     <TextBox
  22.                         Height="23"
  23.                         HorizontalAlignment="Left"
  24.                         Margin="122,49,0,0"
  25.                         Text="{Binding Path=CurrentEmpleado.Nombre, UpdateSourceTrigger=PropertyChanged}"
  26.                         VerticalAlignment="Top"
  27.                         Width="173" />
  28.                     <TextBlock
  29.                         Height="23"
  30.                         HorizontalAlignment="Left"
  31.                         Margin="21,81,0,0"
  32.                         Text="Primer Apellido"
  33.                         VerticalAlignment="Top" />
  34.                     <TextBox
  35.                         Height="23"
  36.                         HorizontalAlignment="Left"
  37.                         Margin="122,78,0,0"
  38.                         VerticalAlignment="Top"
  39.                         Width="173"
  40.                         Text="{Binding Path=CurrentEmpleado.PrimerApellido, UpdateSourceTrigger=PropertyChanged}" />
  41.                     <TextBlock
  42.                         Height="23"
  43.                         HorizontalAlignment="Left"
  44.                         Margin="21,110,0,0"
  45.                         Text="Segundo Apellido"
  46.                         VerticalAlignment="Top" />
  47.                     <TextBox
  48.                         Height="23"
  49.                         HorizontalAlignment="Left"
  50.                         Margin="122,107,0,0"
  51.                         Text="{Binding Path=CurrentEmpleado.SegundoApellido, UpdateSourceTrigger=PropertyChanged}"
  52.                         VerticalAlignment="Top"
  53.                         Width="173" />
  54.                     <TextBlock
  55.                         Height="23"
  56.                         HorizontalAlignment="Left"
  57.                         Margin="21,139,0,0"
  58.                         Text="G?nero"
  59.                         VerticalAlignment="Top" />
  60.                     <ComboBox
  61.                         Height="23"
  62.                         HorizontalAlignment="Left"
  63.                         Margin="122,136,0,0"
  64.                         VerticalAlignment="Top"
  65.                         Width="173"
  66.                         Text="{Binding Path=CurrentEmpleado.Genero, UpdateSourceTrigger=PropertyChanged}">
  67.                         <ComboBoxItem
  68.                             Content="Masculino" />
  69.                         <ComboBoxItem
  70.                             Content="Femenino" />
  71.                     </ComboBox>
  72.                     <TextBlock
  73.                         Height="23"
  74.                         HorizontalAlignment="Left"
  75.                         Margin="21,168,0,0"
  76.                         Text="Puesto"
  77.                         VerticalAlignment="Top" />
  78.                     <ComboBox
  79.                         Height="23"
  80.                         HorizontalAlignment="Left"
  81.                         Margin="122,168,0,0"
  82.                         VerticalAlignment="Top"
  83.                         Width="173"
  84.                         ItemsSource="{Binding Path=ListaPuestos}"
  85.                         SelectedItem="{Binding Path=CurrentEmpleado.Puesto, UpdateSourceTrigger=PropertyChanged}"
  86.                         Text="{Binding Path=CurrentEmpleado.Puesto.Descripcion, UpdateSourceTrigger=PropertyChanged}"
  87.                         DisplayMemberPath="Descripcion" />
  88.                     <DataGrid
  89.                         AutoGenerateColumns="False"
  90.                         Height="288"
  91.                         HorizontalAlignment="Left"
  92.                         Margin="11,217,0,0"
  93.                         Name="dataGrid1"
  94.                         VerticalAlignment="Top"
  95.                         Width="529"
  96.                         ItemsSource="{Binding Path=ListaEmpleados, UpdateSourceTrigger=PropertyChanged}"
  97.                         CanUserAddRows="False">
  98.                         <DataGrid.Columns>
  99.                             <DataGridTextColumn
  100.                                 Binding="{Binding Path=Identificacion, UpdateSourceTrigger=PropertyChanged}"
  101.                                 Header="Identificacion"
  102.                                 Width="100"
  103.                                 IsReadOnly="True" />
  104.                             <DataGridTextColumn
  105.                                 Binding="{Binding Path=Nombre, UpdateSourceTrigger=PropertyChanged}"
  106.                                 Header="Nombre"
  107.                                 Width="125"
  108.                                 IsReadOnly="True" />
  109.                             <DataGridTextColumn
  110.                                 Binding="{Binding Path=PrimerApellido, UpdateSourceTrigger=PropertyChanged}"
  111.                                 Header="Primer Apellido"
  112.                                 Width="150"
  113.                                 IsReadOnly="True" />
  114.                             <DataGridTextColumn
  115.                                 Binding="{Binding Path=Genero, UpdateSourceTrigger=PropertyChanged}"
  116.                                 Header="Genero"
  117.                                 Width="130"
  118.                                 IsReadOnly="True" />
  119.                             
  120.                         </DataGrid.Columns>
  121.                         <i:Interaction.Triggers>
  122.                             <i:EventTrigger
  123.                                 EventName="SelectionChanged">
  124.                                 <cmd:EventToCommand
  125.                                     Command="{Binding SelectionChangedCommand, Mode=OneWay}"
  126.                                     CommandParameter="{Binding SelectedItem, ElementName=dataGrid1}" />
  127.                             </i:EventTrigger>
  128.                         </i:Interaction.Triggers>
  129.                     </DataGrid>
  130.                 </Grid>

 

Para finalizar y desplegar la aplicación modificamos el archivo App.xaml y la sección StartupUri=”View/EmpleadoView.xaml”, la aplicación deberá lucir así:

EmpleadoView

Tal y como lo mencioné en el artículo anterior, he obviado algunos procedimientos con la finalidad de no hacer el post mas grande de lo que ya es, concentrándome en las particularidades que hacen este mantenimiento diferente al anterior que habíamos desarrollado de Puestos.

No me queda mas que agradecer a los lectores que han seguido esta serie de artículos acerca de como implementar el patrón Model-View-ViewModel y en específico utilizando la herramienta MVVM Light Toolkit, ADO.NET Entity Framework y LINQ que eran los objetivos de la serie. Estaré complementado con otros artículos las sugerencias que han manifestado los seguidores del blog, así como también escribiendo acerca de otras funcionalidades que provee MVVM Light Toolkit, como la funcionalidad de “Messenger”, además de escribir algunos artículos trabajando directamente con Microsoft Expression Blend para el diseño de Interfaces ricas en UX en conjunto con MVVM Light Toolkit siempre en la línea de utilizar el patrón para el desarrollo de aplicaciones, así como aplicaciones para Windows Phone 7.

El código fuente de todo el desarrollo de la serie de artículos puede ser descargado aquí :

http://bit.ly/n96yy1

Saludos y nos vemos en el siguiente post.