Silverlight 4 Dica do do Dia #8 Criando um CRUD com MVVM e Silverlight Parte 1 – Retrieve

By rdorta at julho 10, 2010 10:55
Filed Under: Arquitetura, Silverlight, MVVM

Olá,

Uma das coisas que sempre tenho dito em palestras e artigos é que um dos maiores potenciais do Silverlight, se não o maior, é a contrução de aplicações LOB(Line-of-business).

Aplicações deste tipo são aplicações que podem chegar a um grande nível de complexidade dependendo das regras de negócio da empresa que está precisando da aplicação.

Após grandes apelos da comunidade, o Silverlight 4 agora tem suporte a comandos. Isso facilita e muito a implementação de MVVM.

Pensando  nisso e atendendo a alguns pedidos de clientes e amigos, vou criar aqui um exemplo sobre como construir um CRUD simples com Silverlight utilizando o padrão de arquitetura MVVM.

Para iniciar, leiam o post que escrevi sobre MVVM para entender um pouco melhor este padrão.

Em nosso exemplo vamos usar a famosa base Northwind, para gerar as operações de CRUD(Create,Retrieve,Update, Delete). Vamos criar um WCF RIA SERVICE baseado em um modelo criado com Entity Framework.

Montando a Solução

Agora no Visual Studio vamos criar um novo projeto com o template Silverlight Businnes Application

image

Em nosso projeto Silverlight, vamos criar 3 novas pastas, uma para nossas ViewModel,outra para nossos Command e outra para nossas Interfaces.(eu gosto de organizar assim, mas fica a gosto de vocês)

image

Criando a Model de Dados

Agora vamos criar nosso modelo de dados e o serviço que irá recuperar estes dados.

Para manter o exemplo simples, vamos utilizar apenas a tabela Product da base Northwind.

No projeto Web, na pasta Models, clique com o botão direito depois em Add –> New File.

Na aba Data selecione ADO.Net Entity Data Model.

image

No Wizard de criação do EF, selecione Generate from Database e crie/escolha sua conexão com a base Northwind

image

Selecione a tabela de Produto e clique em Finalizar

image

Temos agora nossa Model de Produtos

image

Agora, vamos criar o serviço que expõe os dados dessa model.

NESTE PONTO VOCÊ DEVE COMPILAR SUA APLICAÇÃO PARA QUE NOSSO SERVIÇO ENXERGUE NOSSA MODEL.

Novamente no projeto Web, clique com o botão direito na pasta Services e adicione um novo Domain Service Class

image

No wizard de criação do serviço clique selecione a nossa model de produtos e habilite a edição

image

 

 

 

 

 

 

 

 

Agora temos a nossa classe de serviço:

   1:  
   2: namespace BlogSLMVVM.Web.Services
   3: {
   4:     using System;
   5:     using System.Collections.Generic;
   6:     using System.ComponentModel;
   7:     using System.ComponentModel.DataAnnotations;
   8:     using System.Data;
   9:     using System.Linq;
  10:     using System.ServiceModel.DomainServices.EntityFramework;
  11:     using System.ServiceModel.DomainServices.Hosting;
  12:     using System.ServiceModel.DomainServices.Server;
  13:     using BlogSLMVVM.Web.Models;
  14:  
  15:  
  16:     // Implements application logic using the NorthwindEntities context.
  17:     // TODO: Add your application logic to these methods or in additional methods.
  18:     // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
  19:     // Also consider adding roles to restrict access as appropriate.
  20:     // [RequiresAuthentication]
  21:     [EnableClientAccess()]
  22:     public class NorthwindService : LinqToEntitiesDomainService<NorthwindEntities>
  23:     {
  24:  
  25:         // TODO:
  26:         // Consider constraining the results of your query method.  If you need additional input you can
  27:         // add parameters to this method or create additional query methods with different names.
  28:         // To support paging you will need to add ordering to the 'Products' query.
  29:         public IQueryable<Product> GetProducts()
  30:         {
  31:             return this.ObjectContext.Products;
  32:         }
  33:  
  34:         public void InsertProduct(Product product)
  35:         {
  36:             if ((product.EntityState != EntityState.Detached))
  37:             {
  38:                 this.ObjectContext.ObjectStateManager.ChangeObjectState(product, EntityState.Added);
  39:             }
  40:             else
  41:             {
  42:                 this.ObjectContext.Products.AddObject(product);
  43:             }
  44:         }
  45:  
  46:         public void UpdateProduct(Product currentProduct)
  47:         {
  48:             this.ObjectContext.Products.AttachAsModified(currentProduct, this.ChangeSet.GetOriginal(currentProduct));
  49:         }
  50:  
  51:         public void DeleteProduct(Product product)
  52:         {
  53:             if ((product.EntityState == EntityState.Detached))
  54:             {
  55:                 this.ObjectContext.Products.Attach(product);
  56:             }
  57:             this.ObjectContext.Products.DeleteObject(product);
  58:         }
  59:     }
  60: }
  61:  
  62:  

MVVM RLZ – cRud - Retrieve

Agora vamos ao core do negócio, criar as VielModel e os Comandos.

Vamos começar pela interface.

No projeto Silverlight na pasta Views, adicone uma nova Silverlight Page chamada ProductsView.

Compile e abra o projeto no Expression Blend 4 e abra a ProductsView.xaml.

Adicione 3 botões (Novo,Editar e Excluir), 1 BusyIndicator e 1 DataGrid em sua page.

Adicione a seguinte expressão a propriedade ItemsSource da Datagrid : {Binding AllProducts}

Adicione a seguinte expressão a propriedade IsBusy do BusyIndicato : {Binding IsLoading}

image

Eis o XAML

   1: <navigation:Page 
   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:            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
   7:            xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" x:Class="BlogSLMVVM.Views.ProductsView"
   8:            mc:Ignorable="d"
   9:            d:DesignWidth="640" d:DesignHeight="480"
  10:            Title="ProductsView Page">
  11:     <Grid x:Name="LayoutRoot">
  12:  
  13:         <sdk:DataGrid x:Name="dtgDados" Margin="43,149,48,22" ItemsSource="{Binding AllProducts}"/>
  14:  
  15:         <toolkit:BusyIndicator x:Name="bsiCarregando" Content="BusyIndicator" Height="32" Margin="52,108,71,0" VerticalAlignment="Top" IsBusy="{Binding IsLoading}"/>
  16:         <Button x:Name="btnNovo" Content="Novo" HorizontalAlignment="Left" Height="27" Margin="52,64,0,0" VerticalAlignment="Top" Width="97"/>
  17:         <Button x:Name="btnEditar" Content="Editar" HorizontalAlignment="Left" Height="27" Margin="165,64,0,0" VerticalAlignment="Top" Width="97"/>
  18:         <Button x:Name="btnExcluir" Content="Excluir" Height="27" Margin="275,64,268,0" VerticalAlignment="Top"/>
  19:  
  20:     </Grid>
  21: </navigation:Page>

Vamos criar o link para nossa nova página.

Abra o arquivo MainPage.xaml, localize o StackPanel chamado LinksStackPanel e adicione um divisor e um link para nossa página:

   1: <Rectangle x:Name="Divider1_Copy" Style="{StaticResource DividerStyle}"/>
   2:             <HyperlinkButton x:Name="Link2_Copy" Style="{StaticResource LinkStyle}" 
   3:                 NavigateUri="/ProductsView" TargetName="ContentFrame" Content="Products"/>

Agora vamos criar nossa ViewModel.

No projeto Silverlight, na pasta ViewModel adicione uma nova classe com o nome ProductsViewModel

Abaixo segue o código final da classe, vou comentar os pontos principais mais abaixo.

   1: using System;
   2: using System.Net;
   3: using System.Windows;
   4: using System.Windows.Controls;
   5: using System.Windows.Documents;
   6: using System.Windows.Ink;
   7: using System.Windows.Input;
   8: using System.Windows.Media;
   9: using System.Windows.Media.Animation;
  10: using System.Windows.Shapes;
  11: using System.ComponentModel;
  12: using BlogSLMVVM.Web.Services;
  13: using BlogSLMVVM.Web.Models;
  14: using System.Linq;
  15: using System.ServiceModel.DomainServices.Client;
  16:  
  17: namespace BlogSLMVVM.ViewModel
  18: {
  19:     public class ProductsViewModel : INotifyPropertyChanged
  20:     {
  21:  
  22:         #region Propriedades Privadas
  23:         private NorthwindContext gctxNorthwind = null;
  24:         private bool gIsLoading = false;
  25:         #endregion
  26:  
  27:         #region Propriedades Públicas
  28:         /// <summary>
  29:         ///     Indica se o serviço está ocupado recuperando a listagem
  30:         /// </summary>
  31:         public bool IsLoading
  32:         {
  33:             get { return gIsLoading; }
  34:             set { gIsLoading = value; }
  35:         }
  36:  
  37:         /// <summary>
  38:         ///     Retorna a lista de todos os produtos
  39:         /// </summary>
  40:         public EntitySet<Product> AllProducts
  41:         {
  42:             get { return GetAllProducts(); }
  43:         }
  44:         #endregion
  45:  
  46:         #region Construtor
  47:         public ProductsViewModel()
  48:         {
  49:             gIsLoading = true;
  50:             this.gctxNorthwind = new NorthwindContext();
  51:             this.gctxNorthwind.Load<Product>(
  52:                                this.gctxNorthwind.GetProductsQuery(),
  53:                                delegate(LoadOperation<Product> loadOperation)
  54:                                {
  55:                                    this.IsLoading = false;
  56:                                    RaisePropertyChanged("IsLoading");
  57:                                }, null);
  58:         }
  59:         #endregion
  60:  
  61:         #region Chamadas do Serviço
  62:         /// <summary>
  63:         ///     Chamada para os produtos
  64:         /// </summary>
  65:         /// <returns></returns>
  66:         private EntitySet<Product> GetAllProducts()
  67:         {
  68:             return this.gctxNorthwind.Products;
  69:         }
  70:         #endregion
  71:  
  72:  
  73:         #region INotifyPropertyChanged Members
  74:  
  75:         public event PropertyChangedEventHandler PropertyChanged;
  76:  
  77:         private void RaisePropertyChanged(string propertyname)
  78:         {
  79:             if (PropertyChanged != null)
  80:             {
  81:                 PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
  82:             }
  83:         }
  84:  
  85:         #endregion
  86:     }
  87: }

A primeira coisa é reparar que a classe está implementando a interface INotifyPropertyChanged. Estamos fazendo isso para que a view entenda que houve uma alteração e que ela deve se atualizar.

Em nosso construtor, estamos inicializando o serviço que criamos anteriormente e carregando os Produtos, note que estamos utilizando a propriedade IsLoading para manter a view informada de que o serviço está em execução.

Por fim temos a propriedade AllProducts que retorna a lista de produtos carregada pelo serviço.

Agora vamos ao código da nossa view:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Net;
   5: using System.Windows;
   6: using System.Windows.Controls;
   7: using System.Windows.Documents;
   8: using System.Windows.Input;
   9: using System.Windows.Media;
  10: using System.Windows.Media.Animation;
  11: using System.Windows.Shapes;
  12: using System.Windows.Navigation;
  13: using BlogSLMVVM.ViewModel;
  14:  
  15: namespace BlogSLMVVM.Views
  16: {
  17:     public partial class ProductsView : Page
  18:     {
  19:  
  20:         private ProductsViewModel vmdProduto = null;
  21:  
  22:         public ProductsView()
  23:         {
  24:             InitializeComponent();
  25:             this.vmdProduto = new ProductsViewModel();
  26:             this.DataContext = this.vmdProduto;
  27:         }
  28:  
  29:         // Executes when the user navigates to this page.
  30:         protected override void OnNavigatedTo(NavigationEventArgs e)
  31:         {
  32:         }
  33:  
  34:     }
  35: }

Bem simples, apenas instanciamos a nossa ViewModel e a indicamos como contexto da View.

Pronto!!!

Já estamos com a nossa listagem :)

image 

Eis o fonte utilizado até aqui:

BlogSLMVVM - Parte 1.zip (4,77 mb)

Em breve o próximo post com introdução aos Commands, as outras letras do CRUD e o código fonte final :)

Silverlight 4 Dica do do Dia #8 Criando um CRUD com MVVM e Silverlight Parte 2 – Commands e Insert/Update/Delete

 

Física com Silverlight: YES WE CAN!!! – By William Machado

By rdorta at outubro 22, 2009 09:37
Filed Under: Arquitetura, Silverlight

Olá pessoal, abaixo segue um tutorial muito bom do meu colega de Makesys Willian, que tem se dedicado aos estudo de Silverlight. A equipe da Makesys vem melhorado muito seu conhecimento em Silverlight. Show!!! Obrigado William!!!!

Você vai precisar dos seguinte arquivo para trabalhar com física no Blend:

PhysicsHelper.3.0.0.3.zip (3,60 mb)

Abaixo o código fonte final:

Silverlight_Carro_Fisica.zip (521,23 kb)

By William Machado:

Tutorial: Desenvolvimento em Silverlight 3 utilizando física

No mundo do desenvolvimento de aplicativos baseados na Web, os usuários estão exigindo experiências de aplicativos cada vez mais aprimoradas.

Este tutorial mostra como podemos criar uma aplicação simples em SilverLight utilizando as leis da física. No nosso caso será um carro.

Bom antes de começar vamos entender como funciona. Farseer Physics Engine é um motor de física 2D

que suporta varias plataformas como o XNA da Microsoft, o Silverlight, WPF. Uma das características do Farseer Physics Engine é a simplicidade que permite a criação de diversas aplicações e jogos dinâmicos.

o Farseer Physics Engine é projetado para controlar a posição e rotação de objetos.
No mundo real, as coisas se movem e giram devido as forças aplicadas e torques. Em Farseer, é a mesma coisa. Objetos representam as coisas do mundo real. As forças e torques são aplicados e os organismos reagem de acordo com as leis da física 2D.

Crie um novo projeto selecionando “Silverlight 3 Application”.

clip_image002

Mude o tipo do “LayoutRoot” de “Grid” para “Canvas”.

clip_image004

Adicione o controle “PhysicsControllerBehavior” no LayoutRoot

clip_image006

Ative a propriedade: “MousePickEnabled” para manipular os objetos da tala com o mouse

clip_image008

Agora ou você pode desenhar o carro no próprio Blend ou adicionar uma imagem, no meu caso eu desenhei o carro e adicionei a imagem da roda.

clip_image010

Agrupar as imagens em “Canvas”

clip_image012

Para utilizar o recurso de física temos que incluir a “FarseerPhysics.dll” em nosso projeto.

clip_image014

Agora o projeto deve ser compilado para que os controles de física sejam adicionados no Blend.

clip_image016

Os novos controles que foram adicionados:

clip_image018

Clique e arraste o controle “PhysicsObjectBehavior” nos objetos que terão massa, nesse caso utilizei três uma para o Carro(Path) e outros dois para as rodas(Canvas).

Obs.: aplicar o “PhysicsObjectBehavior” somente nos Canvas das rodas e não nas imagens.

clip_image020

Desenhe um “Rectangle” para ser o chão e aplique o controle de física “PhysicsObjectBehavior”, mas ative a propriedade “IsStatic” do “PhysicsObjectBehavior” para que seja um objeto estático.

clip_image022

Para fazer um “Join” das rodas com o carro precisamos de um objeto intermediário para que possamos utilizar o controle “PhysicsJointBehavior” para isso vamos criar um circulo no meio da roda.

clip_image024

Arraste e solte o controle no circulo.

clip_image026

As propriedades do controle devem ficar assim:

clip_image028

Para isso você pode simplesmente clicar aqui arrastar e soltar encima do carro:

clip_image030

Ok, depois de ter feito o “Join” das rodas com o carro vamos aplicar força na roda para simular o funcionamento motor do carro, para isso precisamos do controle “PhysicsApplyTorqueBehavior”.

Clique arraste e solte o controle encima da roda

clip_image032

Nas propriedades clique em “New”, na seguinte janela escolha o evento “PhysicsKeyTrigger” (para utilizar os eventos do teclado)

clip_image034

 

Selecione uma tecla para acionar o controle

clip_image036

Adicione um valor para “ToqueValue” ex: -5000 para que a roda gire para a esquerda

clip_image038

Repita o mesmo procedimento adicione mais um controle “PhysicsApplyTorqueBehavior”, mas com o valor de “ToqueValue” 5000 para que a roda gire para a direita

clip_image040

Salve a aplicação (CTRL + S) compile (CTRL + SHIFT + B) e execute (F5)

Pronto temos um carro utilizando as leis da física em Silverlight.

Sobre mim

Ricardo Dorta

Ricardo Dorta

Arquiteto de sistemas da Makesys, atua na área de desenvolvimento de aplicações .NET há 5 anos.
MCP, MCAD e MCSD.