Silverlight - Exibir modelo

Neste capítulo, veremos uma técnica importante no desenvolvimento de software do Silverlight, o uso de View Models.

  • o view model é uma peça-chave, que introduz uma técnica chamada apresentação separada, mantendo a vista separada do modelo.

  • View Models oferecem uma maneira de obter uma apresentação separada e veremos como eles exploram a vinculação de dados do Silverlight para reduzir a quantidade de código necessária em sua interface de usuário.

Desafios de desenvolvimento de interface do usuário

View Modelssão projetados para resolver certos problemas que surgem frequentemente durante o desenvolvimento de software de interface de usuário. Talvez o mais importante seja que o código da interface do usuário costuma ser difícil de testar inextricavelmente, especialmente com testes de unidade automatizados. Também existem problemas de qualidade de código que podem afetar a flexibilidade contínua e a capacidade de manutenção de seu código.

  • Se você seguir o caminho de menor resistência ao qual as ferramentas de design do Visual Studio o conduzem, pode acabar colocando código demais no código por trás.

  • É muito comum ver grandes quantidades de funcionalidade do aplicativo serem adicionadas ao código por trás.

  • Poucos desenvolvedores planejariam realmente colocar a lógica de negócios em uma classe de interface do usuário, mas como é onde o Visual Studio coloca seus manipuladores de eventos, ele se torna um lugar muito conveniente para fazer as coisas.

  • É amplamente aceito que o software é mais fácil de desenvolver e manter se as classes tiverem responsabilidades bem definidas e razoavelmente estreitas.

  • O trabalho do code behind é interagir diretamente com os objetos que compõem a interface do usuário onde for necessário.

  • Assim que você começar a colocar o código que toma decisões sobre como seu aplicativo se comporta lá, o que tende a causar problemas.

  • Não apenas a lógica do aplicativo flui para o código que supostamente se preocupa com a interface do usuário, mas alguns desenvolvedores começam a contar com controles e outros objetos da interface do usuário para manter o estado importante do aplicativo.

  • O modelo simplesmente contém os dados, a visualização simplesmente mantém a data formatada e o controlador (ViewModel) atua como a ligação entre os dois. O controlador pode obter a entrada da visualização e colocá-la no modelo e vice-versa.

Apresentação Separada

Para evitar os problemas causados ​​ao colocar a lógica do aplicativo no código ou XAML, é melhor usar uma técnica conhecida como separated presentation. Tendo XAML e code behind com o mínimo necessário para trabalhar com objetos de interface de usuário diretamente, as classes de interface de usuário também contêm código para comportamentos de interação complexos, lógica de aplicativo e tudo o mais, conforme mostrado abaixo no lado esquerdo.

Características importantes da apresentação separada -

  • Com a apresentação separada, a classe de interface do usuário é muito mais simples. Ele tem XAML, é claro, mas o código por trás faz tão pouco quanto é prático.

  • A lógica do aplicativo pertence a uma classe separada, que muitas vezes é chamada de model.

  • Muitos desenvolvedores tentam usar vinculação de dados para conectar elementos no XAML diretamente a propriedades no modelo.

  • O problema é o model preocupa-se inteiramente com o que o aplicativo faz, e não com a forma como o usuário interage com o aplicativo.

  • A maioria das interfaces de usuário tem algum estado que não pertence ao modelo de aplicativo. Por exemplo, se sua interface de usuário usa arrastar e soltar, algo precisa manter o controle de coisas como onde o item que está sendo arrastado está agora, como sua aparência deve mudar conforme ele se move sobre possíveis alvos para soltar e como esses alvos também podem mudar conforme o item é arrastado sobre eles.

  • Esse tipo de estado pode se tornar surpreendentemente complexo e precisa ser totalmente testado.

  • Na prática, você normalmente quer alguma outra aula entre a interface do usuário e o modelo. Isso tem duas funções importantes.

    • Primeiro, ele adapta o modelo do seu aplicativo para uma visão específica da interface do usuário.

    • Em segundo lugar, é onde reside qualquer lógica de interação não trivial e, com isso, quero dizer o código necessário para fazer com que sua interface de usuário se comporte da maneira que você deseja.

Model / View / ViewModel

View Modelé um exemplo da abordagem de apresentação separada, mas sejamos claros sobre exatamente que tipo de coisa temos em cada camada. Existem três camadas -

  • Model
  • View
  • ViewModel

Modelo

Isto é um classic modelo de objeto composto de classes C # comuns que não têm relação direta com a interface do usuário.

Você normalmente espera que seus códigos de modelo sejam capazes de compilar sem referências a nenhuma biblioteca de interface do usuário. Na verdade, você provavelmente seria capaz de pegar exatamente o mesmo código-fonte e compilá-lo em um aplicativo Silverlight, um aplicativo .NET Console comum ou mesmo código da web do lado do servidor.

Os tipos no modelo devem representar os conceitos com os quais seu aplicativo trabalha.

Visão

Uma Visualização é normalmente um UserControl, pode ser sua MainPage ou pode ser apenas alguma parte de sua página.

Na maioria dos aplicativos Silverlight, é uma boa ideia dividir sua interface de usuário em pequenas partes, definindo um UserControl ou Visualização para cada parte.

Os aplicativos Silverlight não são exclusivos nesse aspecto. Algo que é obviamente específico do Silverlight é o View. Quanto mais refinada for a interface do usuário, melhores as coisas tendem a ser. Além de menos propenso a tropeçar em outros desenvolvedores que trabalham nos mesmos arquivos, manter as coisas pequenas e simples desencoraja naturalmente os atalhos que levam a um código semelhante a um espaguete.

Por exemplo, é muito comum definir um View para representar um item individual em uma lista.

ViewModel

Finalmente, para cada View, você escreve um ViewModel. Portanto, esta é uma das características importantes de umViewModel classe.

Ele existe para servir a uma visão particular. oViewModel é especializado em uma maneira particular de apresentar coisas, como um determinado item de dados conforme aparece nas Listas.

É por isso que é chamado de ViewModel; ele adapta o modelo subjacente especialmente para uma visão particular. Como o modelo, oViewModeltambém é uma classe C # comum. Ele não precisa ser derivado de nenhum tipo específico.

Por acaso, alguns desenvolvedores acham conveniente colocar algumas funcionalidades comuns em uma classe ViewModel base, mas o padrão não exige isso. Em particular, seuViewModelnão deriva de nenhum tipo específico do Silverlight. No entanto, ao contrário do modelo, ele pode usar tipos do Silverlight em suas propriedades.

Por exemplo, seu ViewModel pode optar por tornar certas partes de sua interface de usuário visíveis apenas sob certas condições e, portanto, você pode fornecer uma propriedade do tipo System.Windows.Visibility, que é o tipo que os elementos do Silverlight usam para sua propriedade Visibility. Isso torna possível vincular a visibilidade de um elemento, como um painel, diretamente ao ViewModel.

Exemplo

Vejamos um exemplo simples em que usaremos Model-View-ViewModel (MVVM) aproximação.

Step 1 - Crie um novo projeto de aplicativo Silverlight SilverlightMVVMDemo.

Step 2 - Adicione as três pastas (Model, ViewModel e Views) ao seu projeto, conforme mostrado abaixo.

Step 3 - Adicione uma classe StudentModel na pasta Model e cole o código abaixo nessa classe.

using System.ComponentModel; 
 
namespace SilverlightMVVMDemo.Model { 

   public class StudentModel {} 
	
   public class Student : INotifyPropertyChanged { 
      private string firstName; 
      private string lastName;  
		
      public string FirstName { 
         get { return firstName; } 
			
         set {
            if (firstName != value) { 
               firstName = value; 
               RaisePropertyChanged("FirstName"); 
               RaisePropertyChanged("FullName"); 
            } 
         } 
      }
		
      public string LastName { 
         get { return lastName; } 
			
         set { 
            if (lastName != value) { 
               lastName = value; 
               RaisePropertyChanged("LastName"); 
               RaisePropertyChanged("FullName"); 
            } 
         } 
      }  
		
      public string FullName { 
         get { 
            return firstName + " " + lastName; 
         } 
      } 
		
      public event PropertyChangedEventHandler PropertyChanged; 
		
      private void RaisePropertyChanged(string property) { 
         if (PropertyChanged != null) { 
            PropertyChanged(this, new PropertyChangedEventArgs(property)); 
         } 
      } 
   } 
}

Step 4 - Adicione outra classe StudentViewModel na pasta ViewModel e cole o código a seguir.

using SilverlightMVVMDemo.Model; 
using System.Collections.ObjectModel;
  
namespace SilverlightMVVMDemo.ViewModel { 

   public class StudentViewModel { 
	
      public ObservableCollection<Student> Students {  
         get;  
         set;  
      }  
		
      public void LoadStudents() { 
         ObservableCollection<Student> students = new ObservableCollection<Student>(); 
				
         students.Add(new Student { FirstName = "Mark", LastName = "Allain" }); 
         students.Add(new Student { FirstName = "Allen", LastName = "Brown" }); 
         students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });
			
         Students = students; 
      } 
   } 
}

Step 5 - Adicionar Silverlight User Control clicando com o botão direito em Views pasta e selecione Add New Item….

Step 6- Clique em Adicionar. Agora você verá o arquivo XAML. Adicione o seguinte código emStudentView.xaml arquivo, que contém diferentes elementos da IU.

<UserControl x:Class = "SilverlightMVVMDemo.Views.StudentView" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <Grid x:Name = "LayoutRoot" Background = "White">
	
      <StackPanel HorizontalAlignment = "Left">
		
         <ItemsControl ItemsSource = "{Binding Path=Students}">
			
            <ItemsControl.ItemTemplate>
				
               <DataTemplate> 
					
                  <StackPanel Orientation = "Horizontal"> 
                     <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" 
                        Width = "100" Margin = "3 5 3 5"/> 
								
                     <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"  
                        Width = "100" Margin = "0 5 3 5"/> 
								
                     <TextBlock  Text = "{Binding Path = FullName, Mode=OneWay}" 
                        Margin = "0 5 3 5"/> 
								
                  </StackPanel>
						
               </DataTemplate> 
					
            </ItemsControl.ItemTemplate>
				
         </ItemsControl> 
			
      </StackPanel> 
		
   </Grid> 
	
</UserControl>

Step 7 - Agora adicione o StudentView dentro de voce MainPage.xaml arquivo como mostrado abaixo.

<UserControl x:Class = "SilverlightMVVMDemo.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   xmlns:views = "clr-namespace:SilverlightMVVMDemo.Views" 
   mc:Ignorable = "d" 
   d:DesignHeight = "576.316" d:DesignWidth = "863.158"> 
   
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <views:StudentView x:Name = "StudentViewControl" Loaded = "StudentViewControl_Loaded"/> 
   </Grid> 
	
</UserControl>

Step 8 - Aqui está a implementação de Loaded evento no MainPage.xaml.cs arquivo, que irá atualizar o View de ViewModel.

using System.Windows; 
using System.Windows.Controls; 
 
namespace SilverlightMVVMDemo { 

   public partial class MainPage : UserControl { 
	
      public MainPage() { 
         InitializeComponent();
      }
   } 
	
   private void StudentViewControl_Loaded(object sender, RoutedEventArgs e) { 
      SilverlightMVVMDemo.ViewModel.StudentViewModel 
      studentViewModelObject = new SilverlightMVVMDemo.ViewModel.
      StudentViewModel(); 
      studentViewModelObject.LoadStudents();  
      StudentViewControl.DataContext = studentViewModelObject;  
   } 
}

Step 9 - Quando o código acima for compilado e executado, você verá a seguinte saída em sua página da web.

UI vs ViewModel

Uma das partes mais difíceis da abordagem MVVM é descobrir onde deve vir a linha divisória. Nem sempre é óbvio quais coisas pertencem a onde.

  • Em particular, alguns elementos da interface do usuário fornecem funcionalidade que, de acordo com uma View estrita, deve pertencer ao ViewModel.

  • Em geral, nem todos os comportamentos implementados no View são tão ViewModel amigáveis.

  • Parte do motivo para isso é que não existe uma maneira padrão de empacotar o comportamento de ViewModel para reutilização, principalmente se você quiser usar um ambiente de design, como Visual Studio ou Blend.

Vantagens do MVVM

MVVM oferece as seguintes vantagens -

  • Separação de preocupações de apresentação (View, ViewModel, Model)

  • Limpe o código testável e gerenciável. Pode incluir lógica de camada de apresentação em testes de unidade.

  • Nenhum código por trás do código, portanto, a camada de apresentação e a lógica são fracamente acopladas.

  • Melhor forma de ligação de dados.

Desvantagens do MVVM

Para UIs simples, o MVVM pode ser um exagero. A depuração seria um pouco difícil quando temos ligações de dados complexas.