Parte II. Notas Rapidas (sticky notes) App W8: MVVM y SQLite.
1. Parte II. Notas Rapidas (sticky notes) App W8: MVVM y
SQLite.
Antes de comenzar con la parte medular del Modelo, hay que ejemplificar el diseño arquitectónico para el flujo
de la información que va a tener la aplicación utilizando el patrón MVVM, el cual debería de ser de esta forma:
En lo particular he obtenido excelentes resultados al crear clases para cada entidad de negocio e implementar
la interface INotifyPropertyChangeden cada una, de esta forma sepersonalizael desarrollo y a la vez el
encapsulamiento de acceso a datos para que sea accedido por cualquier ViewModel cuando sea solicitado,
de esta forma estas clases en conjunto con Entity Framework pasarían a ser el componente “Model” de
nuestra arquitectura.
Lo primero es crear una clase base y abstracta que nos ayude en la implementación de la interfaz
INotifyPropertyChangedhacia todas las clases de lógica de negocio. El enlace de datos o DataBinding es un
componente básico del modelo MVVM, de esta forma el centro del enlace de datos es la interfaz
INotifyPropertyChanged, esta interfaz aparentemente simple se utiliza para sincronizar los cambios de
propiedad de un objeto con los controles (listbox, texblock, grid, stackpanel, etc) de la interfaz de usuario
(View). Para mayor comprensión del uso de este patrón puedes consultar la página oficial de MVVM.
Bien entonces se va a crear la clase denominada ModeloNotasRapidas, comenzaremos definiendo la
implementación de INotifyPropertyChanged, se tendrá que ver de esta forma:
Ahora se crearan las propiedades y los métodos los cuales estarán en lazados con la clase que va a
manipular las acciones de la base de datos, definiremos estos métodos como CrearNotaRapida,
EliminarNotaRapida, RetornarNotasRapidas. De esta forma se debe de tener:
3. }
#endregion
Por el momento se tienen los elementos básicos para poder iniciar a crear el ViewModel, lo primero que se
debe de realizar es des comentar las líneas de código que por defecto:
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
// Code runs "for real"
}
Donde:
Si IsInDesigMode es Verdadero:
Es cuando se está desarrollando en ExpressionBlend y puedas ver reflejado en modo de
diseño, Si no es así, si el desarrollo lo estas llevando acabo el Visual Studio 2012
debes de poner el código en la parte de Else.
Lo primero que se debe de realizar es la instancia del ModeloNotasRapidas de forma
global privateModeloNotasRapidas modelo, así de esta forma se podrá crear la
sincronizar los cambios de propiedad de un objeto del modelo:
modelo.PropertyChanged += ModeloOnPropertyChanged;
privatevoidModeloOnPropertyChanged(object sender,
PropertyChangedEventArgspropertyChangedEventArgs)
{
switch (propertyChangedEventArgs.PropertyName)
{
case"NotaCreada":
RaisePropertyChanged("NotaCreada");
break;
case"RemoverNota":
RaisePropertyChanged("RemoverNota");
break;
case"ListaNotas":
RaisePropertyChanged("ListaNotas");
break;
}
}
Una vez teniendo esto se debe de considerar el tener cambio de propiedad para cada uno de los
métodos que contenemos en el modelo como lo es el crear, remover y listar las notas rápida para
ello se debe de considera tener propiedades, comandos y métodos de acción, esto debería quedar
de la siguiente forma:
#region Propiedades
publicList<TablaNota>ListaNotas
{
get
{
returnmodelo.ListaNotas;
}
4. }
publicTablaNotanotaSeleccionada;
publicTablaNotaNotaSeleccionada
{
get
{
returnnotaSeleccionada;
}
set
{
notaSeleccionada = value;
RaisePropertyChanged("NotaSeleccionada");
}
}
publicstringdatoNota;
publicstringDatoNota
{
get
{
returndatoNota;
}
set
{
datoNota = value;
RaisePropertyChanged("DatoNota");
}
}
publicstringtitulo;
publicstringTitulo
{
get
{
returntitulo;
}
set
{
titulo = value;
RaisePropertyChanged("Titulo");
}
}
#endregion
#regionComandos
///<summary>
/// Gets AgregarNotaCommand.
///</summary>
publicRelayCommandAgregarNotaCommand
{
get { returnnewRelayCommand(ExecuteAgregarNota); }
}
///<summary>
5. /// Gets EliminarNotaCommand.
///</summary>
publicRelayCommandEliminarNotaCommand
{
get { returnnewRelayCommand(ExecuteEliminarNota); }
}
publicICommandNotaSeleccionadaCommand
{
get;
privateset;
}
#endregion
#regionAccion
privatevoidExecuteNotaSeleccionadaAsync(TablaNotaobj) { }
///<summary>
/// Ejecuta la acción Agregar Nota.
///</summary>
privatevoidExecuteAgregarNota()
{
if(!string.IsNullOrEmpty(DatoNota))
{
modelo.CrearNotaRapida(Titulo, DatoNota);
Titulo = "Titulo";
DatoNota = "";
}
}
///<summary>
///EjecutaaccionEliminar nota
///</summary>
privatevoidExecuteEliminarNota()
{
if (NotaSeleccionada != null)
modelo.EliminarNotaRapida(NotaSeleccionada);
}
#endregion
Para la vista se deben de considerar el tener un usercontrol con el nombre NotasControl el cual
deberá de estar constituido por una ListView este elemento será el que contendrá a las notas por
medio de un datatemplate, al calce del XAML ire puntualizando a detella, entonces debe de estar
de la siguiente manera:
<UserControl
x:Class="NotasRapidas.Views.NotesControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.micros
oft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="650" Width="1356">
<UserControl.Resources>
6. <DataTemplate x:Key="DataTemplate">
<Grid Height="244" Width="241" Margin="25">
<Grid.Background>
<ImageBrushImageSource="ms-
appx:///imagen/stickynote.png" Stretch="UniformToFill"/>
</Grid.Background>
<TextBoxHorizontalAlignment="Left" Height="37" Margin="12,8,0,0"TextWrapping="Wrap"
Text="{BindingTitulo}"VerticalAlignment="Top" Width="106"
Foreground="#FF67E410"TextChanged="TextBox_TextChanged_1" />
<TextBoxHorizontalAlignment="Left" Height="141"
Margin="10,51,0,0"TextWrapping="Wrap" Text="{BindingDato}"VerticalAlignment="Top"
Width="215" Foreground="#FF67E410"TextChanged="TextBox_TextChanged_2" />
<TextBlockHorizontalAlignment="Left" Height="37"
Margin="123,8,0,0"TextWrapping="Wrap" Text="{BindingFecha}"VerticalAlignment="Top"
Width="102" Foreground="#FF67E410"/>
</Grid>
</DataTemplate>
</UserControl.Resources>
Este código muestra el templatede la nota rápida, cuenta con un cambio de propiedad
en su texto para que este se notifique al viewmodel el nuevo texto que contendrá la
nota tanto en título como en información, la apariencia que tendrá el template es la
siguiente:
<Grid>
<BorderBorderBrush="Yellow"CornerRadius="0"BorderThickness="0,0,0,6"
Background="Transparent" Margin="0,0,0,601">
<StackPanel
Orientation="Horizontal"Grid.Row="0"Grid.Column="0"HorizontalAlignment="Center"
Margin="0,0,0,6" Width="315">
<Button x:Name="btnAdd"
Content="Agregar"HorizontalAlignment="Stretch"VerticalAlignment="Bottom"
Background="#FFFBC407" Command="{Binding Path=AgregarNotaCommand}" Height="37"
Click="btnAdd_Click"/>
<Button x:Name="btnDelete"
Content="Eliminar"HorizontalAlignment="Stretch"VerticalAlignment="Stretch"
Background="#FFFBC407" Command="{Binding Path=EliminarNotaCommand}"
Click="btnDelete_Click"/>
</StackPanel>
</Border>
Los Command de Agregar y Eliminar, son enviados al viewmodel para que ahi se procese
una accion ya sea agregar una nota o eliminar una nota.
7. Los eventos click que manejan los botones son unicamente para validar que los textos
no vayan vacios y enviar un mensaje de verificacion.
<Grid Margin="0,54,0,0" Background="#FFF89A1E">
<ListView
x:Name="ListaNotes"ItemTemplate="{StaticResourceDataTemplate}"SelectedItem="{Binding
Path=NotaSeleccionada, Mode=TwoWay}"
ItemsSource="{BindingListaNotas}"
HorizontalAlignment="Left" Width="1356"
IsItemClickEnabled="{BindingNotaSeleccionadaCommand}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGridMaximumRowsOrColumns="4" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
</Grid>
</UserControl>
Dentro de las propiedades que contiene ListView, se agregaran:
SelectedItem una notificación al viewmodel sobre el elemento seleccionado, este nos
servirá para saber cualsera removido.
IsItemClickEnable. Esta acción nos enviara al comando la selección de la nota,
enmarcando el recuadro de la nota.
La apariencia que tendrá el control en general será la siguiente:
8. La apariencia general que deberá de contener el proyecto es la siguiente:
Trate de englobar lo más importante que se utiliza en el patrón MVVM, también
realice algunas adecuaciones para la rotación de la pantalla, por mencionar alguna,
pongo el código compartido para que puedan ver a mayor detalle algunascosas que
omitiera.
Esta aplicación aparecerá próximamente de forma gratuita en el store de Windows.
Cualquier duda o comentario, la contestare de inmediato. Saludos.
Opción 1. Descargar Código
Opción 2. Descargar Código