Windows Phone – MVVM II

En el anterior articulo comenzamos con una mini introducción de MVVM explicando conceptos e indicando que iba a poner ejemplos utilizando el framwork MVVM Light Toolkit, pero antes de empezar con MVVM Light Toolkit voy a realizar un “Hola Mundo” sin ningún framework, el ejemplo va a ser sencillo un TextBox un botón y un combo y la idea es que cuando de al botón lo escrito en el TextBox se añada como item al combobox.

 

Lo primero que tenemos que tener en cuenta que a la hora de crear la estructura del proyecto se recomienda tener una carpeta por cada elemento del patrón, es decir, una para los modelos, otra para las vistas y la ultima para las viewmodels

 

image

Donde en las vistas como hemos dichos tendremos nuestro código XAML y las demás serán clases.

 

Si empezamos por el modelo, aquí tendremos solo una clase con dos propiedades el código del item a insertar en el combo y su descripción que sera la introducida por el usuario. En esta clase estarían todos los accesos a recuperar datos, persistir… de este modelo se llamaría a los servicios web del negocio de este modelo, en este caso no tenemos ninguno.

 

1 namespace HelloWorldMVVM.Models 2 { 3 class Model 4 { 5 public int Code { get; set; } 6 public string Description { get; set; } 7 8 } 9 }

La vista es muy sencilla

 

image

 

Debemos de recordar que el cs del XAML tiene que estar vacio y en nuestro caso debe de ser así.

Si nos centramos ahora en la VistaModelo vamos a crear una nueva clase denominada RelayCommand, esta clase implementara la interfaz ICommand que ya hemos visto en el articulo Commands en WPF, con esta clase definiremos un mecanismo que nos permitirá definir un método que se ejecutara cuando se invoque el comando y aprovechando el método CanExecuteChanged tendremos otro método que nos indicará si el comando se puede lanzar, por ejemplo nosotros vamos a poner que no se puede añadir si el texto introducido no tiene como mínimo 5 caracteres. Esta clase es típica en todos los desarrollos de MVVM

 

1 public class RelayCommand : ICommand 2 { 3 public Predicate<object> CanExecuteDelegate; 4 public Action<object> ExecuteDelegate; 5 6 public bool CanExecute(object parameter) 7 { 8 return CanExecuteDelegate(parameter); 9 } 10 11 public event EventHandler CanExecuteChanged 12 { 13 add { CommandManager.RequerySuggested += value; } 14 remove { CommandManager.RequerySuggested -= value; } 15 } 16 17 public void Execute(object parameter) 18 { 19 ExecuteDelegate(parameter); 20 } 21 }

Esta clase es la que utilizaremos en la creación de los comandos en todas las vistas que veremos mas adelante.

Lo primero es definir en la vista la vista-modelo que va a utilizar y todo ello por XAML aprovechando las características de DataBinding, la manera de hacerlo es muy sencilla

1 <Window x:Class="HelloWorldMVVM.Views.HelloWorldWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:vm="clr-namespace:HelloWorldMVVM.ViewModels" 5 Title="HelloWorldWindow" Height="300" Width="300"> 6 <Window.DataContext> 7 <vm:ViewModel/> 8 </Window.DataContext>

 

Tal y como podéis ver en el código a través de la línea xmlns:vm="clr-namespace:HelloWorldMVVM.ViewModels" hacemos referencia a todas las clase que cuelguen del namespace HelloWorldMVVM.ViewModels y en la propiedad DataContext seleccionamos la clase ViewModel que queremos utilizar. Como utilizamos DataBinding debemos recordar que tenemos que implementar la interfaz INotifyPropertyChanged una vez implementada vamos a definir una propiedad que serán los items del combobox de tipo ObservableCollection de nuestro Model y una propiedad para el texto del nuevo item

 

En esta clase nos quedaría una ultima propiedad que será el comando enlazado con el botón utilizando la clase RelayCommand

 

1 #region Properties 2 3 public string NewItem 4 { 5 get 6 { 7 return _newItem; 8 } 9 10 set 11 { 12 _newItem = value; 13 NotifyPropertyChanged("NewItem"); 14 } 15 } 16 17 18 public Model SelectedItem 19 { 20 get 21 { 22 return _selectedItem; 23 } 24 set 25 { 26 _selectedItem = value; 27 NotifyPropertyChanged("SelectedItem"); 28 } 29 } 30 31 32 public ObservableCollection<Model> Items { get; set; } 33 34 35 #region AddItemCommand 36 37 public ICommand AddItemCommand 38 { 39 get 40 { 41 this._AddItemCommand = new RelayCommand() 42 { 43 CanExecuteDelegate = p => CanAddNewItem(), 44 ExecuteDelegate = p => AddItem() 45 }; 46 return this._AddItemCommand; 47 } 48 } 49 50 private void AddItem() 51 { 52 Model newItem = new Model(); 53 newItem.Code = Items.Count == 0 ? 1 : Items[Items.Count - 1].Code + 1; 54 newItem.Description = NewItem; 55 SelectedItem = newItem; 56 57 Items.Add(newItem); 58 59 } 60 61 private bool CanAddNewItem() 62 { 63 return NewItem.Length > 5; 64 } 65 66 #endregion 67 68 #endregion

Debemos fijarnos como hemos creado la propiedad AddItemCommand derivada de ICommand utilizando la clase RelayComand para enlazar los métodos CanAddNewItem y AddItem.

 

Ahora vamos a enlazar todo en la vista a través del Binding

1 <Window x:Class="HelloWorldMVVM.Views.HelloWorldWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:vm="clr-namespace:HelloWorldMVVM.ViewModels" 5 Title="HelloWorldWindow" Height="300" Width="300"> 6 <Window.DataContext> 7 <vm:ViewModel/> 8 </Window.DataContext> 9 <Grid> 10 <TextBlock Height="23" HorizontalAlignment="Left" Margin="16,23,0,0" Name="textBlock1" Text="Introduce el texto a insertar:" VerticalAlignment="Top" /> 11 <TextBox Height="24" Text="{Binding Path=NewItem, Mode=TwoWay}" HorizontalAlignment="Left" Margin="175,20,0,0" Name="txtTextToÏnsert" VerticalAlignment="Top" Width="91" /> 12 <Button Content="Insertar" Command="{Binding AddItemCommand}" Height="21" HorizontalAlignment="Left" Margin="80,67,0,0" Name="btnAdd" VerticalAlignment="Top" Width="80" /> 13 <TextBlock Height="18" HorizontalAlignment="Left" Margin="16,122,0,0" Name="textBlock2" Text="Items:" VerticalAlignment="Top" Width="53" /> 14 <ComboBox Height="20" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" DisplayMemberPath="Description" HorizontalAlignment="Left" Margin="66,122,0,0" Name="cboItems" VerticalAlignment="Top" Width="187" /> 15 </Grid> 16 </Window>

El comando lo enlazamos al botón el TextBlock a la propiedad NewItem,la propiedad Items al Combo.

 

Tenéis el código para descargarlo y ver mejor la implementación que es un poco complicada de seguir

Download File – HelloWorldMVVM

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *