BrSilverlight

Tutoriais e dicas sobre Silverlight

Sobre o autor

Sou Breno Ferreira, desenvolvedor em um Centro de Tecnologia em Petrópolis especializado em Silverlight. Criei este site com o objetivo de postar dicas, tutoriais e artigos sobre Silverlight, WPF e tecnologias Microsoft.

 

Formulários em Silverlight com o controle DataForm

Introdução

O Silverlight é uma plataforma muito boa para construção de aplicações Line-of-Business, que oferecem uma interface rica e que responde rapidamente ao usuário.

Neste tutorial, irei explicar como criar um formulário de cadastro em Silverlight, usando o controle DataForm, e aplicando o Pattern MVVM para expor os dados ao UserControl do Silverlight. Caso voce não conheça o pattern, leia um tutorial postado anteriormente neste site que explica como o pattern funciona.

O código deste tutorial está disponível no meu Skydrive:

http://cid-1498c467c14dc20b.skydrive.live.com/self.aspx/BrSilverlight/Tutoriais/GameStore.zip

Criando o projeto

Como nossa aplicação será um esboço de uma aplicação LOB, criaremos uma NavigationApplication, que já inclui por padrão um sistema de navegação, parecido com páginas Web. Apesar de termos somente uma “página” nesta aplicação, acho que esse padrão é interessante para aplicações LOB.

Para criar um projeto do tipo NavigationApplication, vá em New Project no Visual Studio, e escolha a opção Silverlight Navigation Application.

image

Model

Neste tutorial, iremos criar um formulário para cadastro de jogos. Iremos guardar dados como nome, numero de jogadores, categoria, avaliação e a URL do site.

Crie uma nova classe chamada Game e adicione as seguintes propriedades.

Game.cs
  1. public class Game
  2. {
  3.     [Required(ErrorMessage="Game name is required")]
  4.     public String Name { get; set; }
  5.  
  6.     [RegularExpression(@"((https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)", ErrorMessage="Invalid Website ULR")]
  7.     public String Website { get; set; }
  8.  
  9.     [Required(ErrorMessage="Number of Players is required")]
  10.     public int NumberOfPlayers { get; set; }
  11.  
  12.     [Range(0, 1)]
  13.     public Double Rating { get; set; }
  14.  
  15.     [Required(ErrorMessage="Category is required")]
  16.     public String Category { get; set; }
  17. }

 

Snippet 1

Essa classe será o Model na nossa aplicação, guardando as informações dos games.

Obs: Note que as propriedades estão marcadas com alguns Attributes. Ignore

ViewModel

O ViewModel neste exemplo será bastante simples. Será utilizado somente para expor os dados para a nossa View. Adicione a classe GameViewModel ao projeto e o seguinte código:

GameViewModel.cs
  1. public class GameViewModel : INotifyPropertyChanged
  2. {
  3.     public GameViewModel()
  4.     {
  5.         this.CreateGames();
  6.     }
  7.  
  8.     private void CreateGames()
  9.     {
  10.         List<Game> games = new List<Game>();
  11.  
  12.         Game game1 = new Game();
  13.         game1.Name = "Halo 3";
  14.         game1.Rating = 1;
  15.         game1.NumberOfPlayers = 4;
  16.         game1.Website = "http://halo.xbox.com/halo3/";
  17.         var game1Category = "Shooter";
  18.         game1.Category = game1Category;
  19.  
  20.         games.Add(game1);
  21.  
  22.         Game game2 = new Game();
  23.         game2.Name = "Gears of War 2";
  24.         game2.Rating =0.8;
  25.         game2.NumberOfPlayers = 10;
  26.         game2.Website = "http://gearsofwar.xbox.com/";
  27.         game2.Category = game1Category;
  28.  
  29.         games.Add(game2);
  30.  
  31.         Game game3 = new Game();
  32.         game3.Name = "Fifa Soccer 10";
  33.         game3.Rating = 0.7;
  34.         game3.NumberOfPlayers = 4;
  35.         game3.Website = "http://fifa.easports.com/";
  36.  
  37.         var game3Category = "Sports";
  38.         game3.Category = game3Category;
  39.  
  40.         games.Add(game3);
  41.  
  42.         this.Games = games;
  43.     }
  44.  
  45.     private List<Game> games;
  46.     public List<Game> Games
  47.     {
  48.         get { return games; }
  49.         private set { games = value; OnPropertyChanged("Games"); }
  50.     }
  51.  
  52.     public event PropertyChangedEventHandler PropertyChanged;
  53.  
  54.     private void OnPropertyChanged(String propertyName)
  55.     {
  56.         if (this.PropertyChanged != null)
  57.             this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  58.     }
  59. }

 

 

 

Snippet 2

No nosso ViewModel, criamos uma propriedade chamada Games do tipo List<Game>. Essa propriedade será utilizada pela nossa View para mostrar os dados dos games cadastrados. O método CreateGames cria alguns objetos iniciais, somente para o objetivo de demonstração deste exemplo.

Obs: Note que esta classe implementa a interface INotifyPropertyChanged, que serve para notificar a View de que a propriedade do nosso ViewModel foi modificada, atualizando as informações na tela.

View

Como no nosso projeto iremos utilizar alguns controles do Silverlight Tookit, iremos adicionar as seguintes DLLs ao nosso projeto:

  • System.Windows.Controls.Data.DataForm.Toolkit.dll
  • System.Windows.Controls.Input.Toolkit.dll

Como na versão Beta 2 do Visual Studio 2010 há um pequeno bug na hora de adicionar referências a DLLs, voce terá que navegar até a pasta onde está instalado o Silverlight Control Toolkit e adicionar as DLLs. Geralmente, o Toolkit está instalado em:

C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Toolkit\Bin

Nossa View, que irá conter o controle DataForm, será o Home.xaml, na pasta Views do projeto. Adicione o Xaml abaixo no arquivo Home.xaml.

Code Snippet
  1. <navigation:Page x:Class="GameStore.Home"
  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" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5.     xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
  6.     xmlns:dt="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
  7.     xmlns:in="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
  8.     xmlns:vm="clr-namespace:GameStore.ViewModel"
  9.     mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
  10.     Title="Home"
  11.     Style="{StaticResource PageStyle}">
  12.     
  13.     <UserControl.Resources>
  14.         <vm:GameViewModel x:Key="ViewModel" />
  15.     </UserControl.Resources>
  16.  
  17.     <Grid x:Name="LayoutRoot" DataContext="{StaticResource ViewModel}">
  18.         <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}">
  19.  
  20.             <StackPanel x:Name="ContentStackPanel">
  21.  
  22.                 <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}"
  23.                            Text="Welcome to the Game Store"/>
  24.  
  25.                 <dt:DataForm AutoGenerateFields="False" AutoEdit="False" ItemsSource="{Binding ElementName=LayoutRoot, Path=DataContext.Games}">
  26.                     <dt:DataForm.EditTemplate>
  27.                         <DataTemplate>
  28.                             <StackPanel dt:DataField.IsFieldGroup="True">
  29.                                 <dt:DataField Label="Name:" Description="Name of the game">
  30.                                     <TextBox Text="{Binding Path=Name, Mode=TwoWay}" />
  31.                                 </dt:DataField>
  32.                                 <dt:DataField Label="Website:" Description="Website of the game">
  33.                                     <TextBox Text="{Binding Path=Website, Mode=TwoWay}" />
  34.                                 </dt:DataField>
  35.                                 <dt:DataField Label="Number of Players" Description="Number of players supported by the game" >
  36.                                     <in:NumericUpDown Minimum="1" Value="{Binding Path=NumberOfPlayers, Mode=TwoWay}" Width="70" HorizontalAlignment="Left" />
  37.                                 </dt:DataField>
  38.                                 <dt:DataField Label="Rating" Description="How good is this game?">
  39.                                     <in:Rating ItemCount="5" Value="{Binding Path=Rating, Mode=TwoWay}" />
  40.                                 </dt:DataField>
  41.                                 <dt:DataField Label="Category" Description="Game category (Shooter, Sports, Action, ...)">
  42.                                     <TextBox Text="{Binding Path=Category, Mode=TwoWay}" />
  43.                                 </dt:DataField>
  44.                             </StackPanel>
  45.                         </DataTemplate>
  46.                     </dt:DataForm.EditTemplate>
  47.                 </dt:DataForm>
  48.  
  49.             </StackPanel>
  50.  
  51.         </ScrollViewer>
  52.     </Grid>
  53.  
  54. </navigation:Page>

Snippet 3

O controle DataForm

No Silverlight Tookit, existe um controle muito bom para a construção de formulários para receber dados do usuário. É um controle muito fácil de usar, e também muito flexível. Voce pode optar por gerar os campos automaticamente (setando a propriedade AutoGenerateFields para True), ou então especificar explicitamente quais controles serão utilizados para mostrar os dados. No nosso caso, setamos a propriedade AutoGenerateFields para false e customizamos a aparência do Form, definindo o EditTemplate do DataForm.

A maneira mais fácil de definir os controles utilizados no Form é criando um StackPanel que irá conter vários DataFields, que irão conter os Labels e terão como Content o controle que irá apresentar/receber a informação do usuário.

Nesse exemplo, temos vários DataFields, cada um com um controle Databound que irá apresentar/receber os dados do usuário. Por exemplo, utilizamos uma TextBox para o nome do game, um NumericUpDown para o número de jogadores, um Rating para a avaliação do jogo, etc… Note que em cada DataField setamos as propriedades Label (precisa explicar?) e Description (uma informação extra que é mostrada ao usuário sobre uma propriedade em particular.

Obs: usamos TwoWay Binding nos controles, assim quando o usuário editar as informações de um game, elas serão automaticamente atualizadas no noss Model.

Quando rodamos a aplicação, veremos o seguinte resultado:

image

 

 

 

 

Model Revisited

Lembra-se daqueles Attributes que definimos nas propriedades do nosso Model? Eles servem para fazermos validação dos dados digitados pelo usuário. Por exemplo:

O Attribute Required indica que o usuário precisa preencher o campo respectivo a propriedade marcada com esse Attribute. No nosso exemplo, as propriedades Name, NumberOfPlayers e Category. Esse Attribute também permite definir uma mensagem de erro que é apresentada ao usuário caso o usuário não preencha o campo.

Outro attribute interessante é o o RegularExpression, que permite que a validação de um campo através de uma Regular Expression. Usamos esse Attribute na propriedade Website, e definimos também uma ErrorMessage caso a Regex falhe.

Outro Attribute que também usamos é o Range, que define entre quais valores uma propriedade numérica pode estar.

Para saber mais sobre outros Attributes de validação, acesse a documentação do Namespace System.ComponentModel.DataAnnotations em http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx.

Quando inserimos alguma entrada inválida no DataForm, e clicamos em OK (quando editando ou adicionando um item novo), as mensagens de erro são automaticamente mostradas, conforme a imagem abaixo:

image 

 

Quando corrigimos os erros, e clicamos em OK, as mensagens somem e o novo game é adicionado a Collection no nosso ViewModel.

image


Categories: Silverlight
Permalink | Comentários (0) | Post RSSRSS comment feed

Novidades do Silverlight 4 – Parte IV: o Pattern MVVM (Model-View-ViewModel)

Introdução

Nos posts anteriores, iniciei uma série de tutoriais que cobre algumas das novas features do Silverlight 4, e escrevi especificamente sobre Elevated Trust em aplicações Out-of-Browser, como ler o feed RSS dos webcasts no MSDN, e utilizar a interface COM do Outlook para adicionar um item ao calendário.

Hoje, irei explicar como criar a UI da aplicação e utilizar o Pattern MVVM para fazer a separação do XAML (interface) e do código utilizando Bindings e a nova Interface do Silverlight 4, ICommand.

Voce pode baixar o código deste tutorial no link abaixo:

http://cid-1498c467c14dc20b.skydrive.live.com/self.aspx/BrSilverlight/Tutoriais/MsdnWebcastsCalendar.zip

Como funciona o MVVM?

MVVM é um Pattern Arquitetural que tem como objetivo promover uma separação de responsabilidades. A camada de apresentação (View) fica responsável somente por receber os dados (Model), e apresentá-los ao usuário, enquanto há uma camada intermediária (ViewModel) que fica responsável por toda a lógica de negócio, e expor os dados para a respectiva View. Resumindo:

  • Model: é a estrutura de dados que expõe as informações sobre o que desejamos apresentar ao usuário
  • View: define a interface de usuário (XAML)
  • ViewModel: trata as ações do usuário, como por exemplo o click de um botão, e expõe os Models a View

Quando se aplica o Pattern a aplicações Silverlight ou WPF, a ligação dos Models é feita com a utilização de DataBinding e os eventos podem ser tratados utilizando-se Commands ou a API de Triggers do Expression Blend.

Analise a figura abaixo para visualizar melhor os tres elementos do Pattern:

image

Figura 1

 

MVVM na prática

Até aqui, já criamos algumas classes que possuem algumas funcionalidades como:

RssReader: lê os feeds RSS dos webcasts MSDN;

OutlookApplication: chama a API COM do Outlook para criar um item no calendário.

Essas classes farão parte da nossa lógica de negócio.

Agora, iremos criar os tres elementos que compoem o Pattern MVVM.

Model

Nós já criamos o Model da nossa aplicação na parte II. O Model da nossa aplicação será a classe FeedItemModel. Ela irá guardar as informações lidas do XML do RSS dos webcasts. Abaixo, o código da classe FeedItemModel:

Code Snippet
  1. public class FeedItemModel
  2. {
  3.     public String Title { get; set; }
  4.     public Uri Link { get; set; }
  5.     public DateTime Date { get; set; }
  6.     public Int32 Duration { get; set; }
  7.     public String Creator { get; set; }
  8.     public String Description { get; set; }
  9. }

Snippet 1

ViewModel

Code Snippet
  1. public class FeedViewModel : INotifyPropertyChanged
  2. {
  3.     public FeedViewModel ( )
  4.     {
  5.         this.ReadRssFeeds ( );
  6.     }
  7.  
  8.     public ObservableCollection<FeedItemModel> Feeds { get; private set; }
  9.     public ICommand OutlookApplicationCommand { get { return new OutlookCommand ( ); } }
  10.  
  11.     private void ReadRssFeeds ( )
  12.     {
  13.         RssReader reader = new RssReader ( );
  14.         reader.RssFeedReadCompleted += new EventHandler<RssFeedReadCompletedEventArgs> ( reader_RssFeedReadCompleted );
  15.         reader.ReadRssFeedAsync ( new Uri ( "http://www.msdnbrasil.com.br/Microsoft.NewRSS/RssItems.aspx?segment=Arquiteto%20de%20Solu%C3%A7%C3%B5es--and--Desenvolvedores&type=WebCasts%20Online&futureitems=S&auth=747dab31-42e3-69f3-7765-618e61722d9a" ) );
  16.     }
  17.  
  18.     void reader_RssFeedReadCompleted ( object sender, RssFeedReadCompletedEventArgs e )
  19.     {
  20.         if ( this.Feeds == null )
  21.             this.Feeds = new ObservableCollection<FeedItemModel> ( );
  22.  
  23.         Array.ForEach ( e.Feeds.ToArray ( ), ( feed ) => this.Feeds.Add ( feed ) );
  24.         OnPropertyChanged ( "Feeds" );
  25.     }
  26.  
  27.     #region INotifyPropertyChanged Members
  28.  
  29.     public event PropertyChangedEventHandler PropertyChanged;
  30.  
  31.     private void OnPropertyChanged ( string propertyName )
  32.     {
  33.         if ( PropertyChanged != null )
  34.         {
  35.             PropertyChanged ( this, new PropertyChangedEventArgs ( propertyName ) );
  36.         }
  37.     }
  38.  
  39.     #endregion

Snippet 2

Como um dos objetivos do ViewModel é expor os dados do Model para a View, temos a propriedade Feeds, que é uma ObservableCollection de FeedItemModels.

No construtor da classe, chamamos o método ReadRssFeeds, que por sua vez irá utilizar um objeto do tipo RssReader, que irá ler os feeds RSS. Quando a leitura dos feeds RSS terminar, o método reader_RssFeedReadCompleted será chamado, onde iremos adicionar todos os itens lidos a nossa coleção de FeeditemModels (Feeds).

Importante!

Nosso ViewModel implementa a Interface INotifyPropertyChanged. Temos implementar essa interface para notificar a View que nossa propriedade Feeds sofreu modificações (quando adicionamos os feeds a ela). Assim a engine de Databinding poderá atualizar os valores dos controles na nossa View. Internamente, a engine de Databinding irá associar o evento PropertyChanged, que irá atualizar os controles que fazem Binding com as propriedades dos objetos da classe FeedItemModel. Experimente comentar a parte onde chamamos o método OnPropertyChanged (linha 24) e voce verá que não irá aparecer nada na tela.

No nosso ViewModel, temos uma propriedade chamada OutlookApplicationCommand do tipo ICommand. Commands são uma nova feature do Silverlight 4 (que já existia em WPF), que facilita a implementação do Pattern MVVM.

Crie uma classe chamada OutlookCommand e adicione o código abaixo:

Code Snippet
  1. public class OutlookCommand : ICommand
  2. {
  3.     #region ICommand Members
  4.  
  5.     public event EventHandler CanExecuteChanged;
  6.  
  7.     public bool CanExecute ( object parameter )
  8.     {
  9.         return OutlookApplication.IsAvailable;
  10.     }
  11.  
  12.     public void Execute ( object parameter )
  13.     {
  14.         FeedItemModel model;
  15.         if(parameter is FeedItemModel)
  16.             model = parameter as FeedItemModel;
  17.         else
  18.             throw new ArgumentException("Invalid argument", "parameter");
  19.  
  20.         try
  21.         {
  22.             OutlookApplication.CreateCalendarItem ( model );
  23.             MessageBox.Show("Webcast added to your Outlook Calendar");
  24.         }
  25.         catch ( Exception )
  26.         {
  27.             MessageBox.Show ( "An error ocurred when trying to open Outlook resources.\nMake sure you have Microsoft Outlook for Windows installed and properly configured." );
  28.         }
  29.     }
  30.  
  31.     #endregion
  32. }

Snippet 3

A classe OutlookCommand implementa a interface ICommand, que possui os seguintes métodos:

CanExecute: esse método é responsável por dizer se o Command pode ou não ser executado. Assim, quando associarmos esse Command com um botão na nossa View, caso este método retorne false, o botão ficará desabilitado. No nosso caso, retornamos o valor da propriedade “IsAvailable” da classe OutlookApplication (ver a Parte III desta série de tutoriais).

Execute: esse método executa a ação (neste caso, inserir o item no calendário do Outlook com as informações do Webcast). Note que esse método, assim como o método CanExecute, recebe um parâmetro. Veremos abaixo como passar esse parâmetro pelo XAML. Esse parâmetro deve ser do tipo do nosso Model (FeedItemModel). Caso não seja, lançamos uma Exception.

View

Nossa View será representada pelo UserControl MainPage, que terá o seguinte XAML:

Code Snippet
  1. <UserControl x:Class="MsdnWebcastsCalendar.MainPage"
  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:vm="clr-namespace:MsdnWebcastsCalendar.ViewModel"
  7.     mc:Ignorable="d"
  8.     Width="800" Height="600">
  9.  
  10.     <UserControl.Resources>
  11.         <vm:FeedViewModel x:Key="FeedViewModelDataContext" />
  12.         <Style x:Key="ListBoxItemTemplate" TargetType="ListBox">
  13.             <Setter Property="ItemTemplate">
  14.                 <Setter.Value>
  15.                     <DataTemplate>
  16.                         <StackPanel Width="{Binding ElementName=LayoutRoot, Path=ActualWidth}">
  17.                             <StackPanel.Background>
  18.                                 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  19.                                     <GradientStop Color="#FF36295E" Offset="0"/>
  20.                                     <GradientStop Color="#FFA2DCF3" Offset="1"/>
  21.                                 </LinearGradientBrush>
  22.                             </StackPanel.Background>
  23.                             <StackPanel Orientation="Horizontal">
  24.                                 <Button Command="{Binding ElementName=LayoutRoot, Path=DataContext.OutlookApplicationCommand}"
  25.                                         CommandParameter="{Binding}"
  26.                                         ToolTipService.ToolTip="Adicionar webcast ao calendário do Outlook">
  27.                                     <Image Source="/MsdnWebcastsCalendar;component/Microsoft_Outlook.png" />
  28.                                 </Button>
  29.                                 <HyperlinkButton Margin="0, 11, 0, 0" Content="{Binding Path=Title}" NavigateUri="{Binding Path=Link}" />
  30.                             </StackPanel>
  31.                             <TextBox Text="{Binding Path=Description}" IsReadOnly="True" TextWrapping="Wrap" />
  32.                             <StackPanel Orientation="Horizontal">
  33.                                 <TextBlock Text="Data: " FontStyle="Italic" />
  34.                                 <TextBlock Text="{Binding Path=Date}" FontStyle="Italic" />
  35.                                 <TextBlock Text="-" />
  36.                                 <TextBlock Text="{Binding Path=Creator}" FontWeight="Bold" />
  37.                             </StackPanel>
  38.                         </StackPanel>
  39.                     </DataTemplate>
  40.                 </Setter.Value>
  41.             </Setter>
  42.         </Style>
  43.     </UserControl.Resources>
  44.  
  45.     <Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Source={StaticResource FeedViewModelDataContext}}">
  46.         <ListBox x:Name="feedsListBox" Style="{StaticResource ListBoxItemTemplate}" ItemsSource="{Binding Path=Feeds}" />
  47.     </Grid>
  48. </UserControl>

Snippet 4

Aqui, nós temos uma ListBox que irá mostrar as informações dos feeds RSS dos Webcasts MSDN. Para explicar os detalhes do XAML acima, decidi separar em alguns tópicos.

Referenciando o ViewModel na View

Para unir o ViewModel a View da aplicação, iremos criar um objeto do tipo do nosso ViewModel (FeedViewModel) no XAML. Isso pode ser feito adicionando o XML Namespace com referencia ao namespace do nosso ViewModel (veja linha 6), e guardando o ViewModel como uma resource do UserControl, criando-se uma Key, para que possamos referenciá-lo mais tarde (linha 11).

Configurando os Bindings

No Grid LayoutRoot, definimos a propriedade DataContext, que irá guardar a referência para o ViewModel. Assim poderemos usar DataBinding para mostrar os valores dos Feeds RSS nos controles.

Logo abaixo, na Listbox (linha 46), a propriedade ItemsSource recebe o valor da propriedade Feeds do ViewModel (a propriedade Path do Binding recebe o nome da propriedade do objeto que é usado como fonte de dados no DataBinding, no nosso caso, o ViewModel).

No style dos Items da ListBox, também utilizamos DataBinding para setar os valores dos controles que irão mostrar os dados do Webcast. Por exemplo, na linha 31, temos uma TextBox que recebe o valor da propriedade Description, um HyperLinkButton que recebe o valor da propriedade Link, etc…

Importante!

No estilo definido para nossa ListBox, o objeto que é a fonte de DataBinding é um dos items da ObservableCollection Feeds do FeedViewModel. Isso por que a propriedade ItemsSource da ListBox, recebe a referência da propriedade Feeds, e os controles definidos no estilo são usados para cada ListBoxItem criada.

Resumindo: a propriedade ItemsSource recebe o valor da propriedade Feeds do nosso ViewModel. Isso irá criar vários ListBoxItems. E cada ListBoxItem terá como fonte de dados para o DataBinding, um elemento da ObservableCollection Feeds.

Configurando o Command

Cada ListBoxItem terá um botão que terá como Command, o Command definido no nosso ViewModel (OutlookApplicationCommand). Para definirmos isso no XAML, utilizamos Binding de elemento para elemento. Na linha 24, onde criamos o botão, definimos a propriedade Command utilizando Binding, e definimos a fonte como a propriedade OutlookApplicationCommand do DataContext (FeedViewModel) do controle LayoutRoot. Também passamos como parâmetro (que é passado para o método Execute do Command), a fonte de Binding do ListBoxItem (FeedItemModel).

Quando rodarmos nossa aplicação, teremos o seguinte resultado (lembre-se que para utilizarmos a API do Outlook, temos que rodar Out-of-Browser com Elevated Permissions):

image

Quando clicarmos no botão com o ícone do Outlook, ele irá chamar o método Execute do OutlookCommand, adicionando um item no calendário do Outlook com as informações do Webcast, conforme as imagens abaixo.

image

image

Bem, chegamos ao final dessa série de tutoriais. Espero que o conteúdo tenha ficado claro para todos. Caso alguma coisa não tenha ficado clara, ou alguma dúvida não foi respondida, não exite em deixar um comentário ou entre em contato comigo (http://brsilverlight.com/contact.aspx) ou mande uma mensagem para mim no Twitter (http://twitter.com/breno_ferreira).


Permalink | Comentários (0) | Post RSSRSS comment feed

Novidades do Silverlight 4 – Parte I: Rodando Out-of-Browser com Elevated Permissions

Introdução

Essa é a primeira parte de uma série de tutoriais que irá cobrir alguns dos novos recursos do Silverligtht 4, como Elevated Permisions em aplicações Out-of-Browser, MVVM usando a interface ICommand e COM Interop, a única feature nova que, ainda, não é multi-plataforma, ou seja, somente funciona em Windows.

Neste tutorial, iremos criar uma aplicação que irá ler um feed RSS dos próximos Webcasts do MSDN Brasil, e que também deixará o usuário salvar a data do webcast no seu calendário no Outlook usando COM Interop, caso a aplicação esteja rodando fora do browser, com privilégios elevados.

Voce pode baixar o código deste tutorial no link abaixo:

http://cid-1498c467c14dc20b.skydrive.live.com/self.aspx/BrSilverlight/Tutoriais/MsdnWebcastsCalendar.zip

Elevated Permissions no Silverlight 4

No Silverlight 4, a pedido de vários clientes e membros da comunidade, o time de Silverlight da Microsoft introduziu um novo recurso, que permite aplicações Silverlight rodando fora do browser usufruam de alguns recursos a mais que eram restringidos pela Sandbox de segurança. Alguns desses recursos são:

  • Acesso a arquivos locais: com isso é possível acessar as pastas My* (MyDocuments, MyMusic, MyVideos, …) do usuário sem precisar utilizar as APIs OpenFileDialog e SaveFileDialog. Basta utilizar-se as classes do namespace System.IO.
  • Chamadas a recursos Cross-Domain: com isso é possível acessar recursos que se encontram fora do domínio da aplicação Silverlight sem a necessidade de haver arquivos de configuração cross-domain (clientacesspolicy.xml ou crossdomain.xml).
  • COM Interop: agora é possível acessar recursos disponíveis através de interfaces COM. Note que esta feature está disponível somente em ambientes Microsoft Windows, pois no MacOS não existe COM.
  • e vários outros

Para começarmos, crie uma nova aplicação Silverlight no Visual Studio e dê o nome MsdnWebcastsCalendar (ou o nome que voce preferir). Com a aplicação criada, clique com o botão direito no projeto e vá em “Propriedades”. Agora execute os seguintes passos:

  1. na guia “Silverlight”, marque a opção “Enable running application out of browser”
  2. clique no botão “Out-of-Browser Settings …”
  3. marque a check-box “Require elevated trust when running outside of the browser”.

image

Agora, precisamos instalar a aplicação em nossa máquina. Para isso, devemos executar a aplicação, clicar com o botão direito e clicar em “Intall MsdnWebcastsCalendarApplication onto this computer …”. Uma caixa de diálogo irá abrir, pedindo ao usuário que instale a aplicação em sua máquina. Note que há uma aviso de segurança, notificando o usuário de que a aplicação poderá acessar recursos locais da máquina. Isso é um recurso de segurança que irá previnir os usuários de instalarem aplicações de origens não confiáveis. Clique em “Install”.

image

Agora a aplicação está instalada na máquina do usuário. Como ainda estamos desenvolvendo a aplicação, iremos configurar o Visual Studio para debugar a aplicação fora do browser.

Vá de novo nas propriedades do projeto Silverlight, e desta vez, vá em “Debug”, e marque a terceira opção “Installed out-of-browser application”.

image

Agora temos nossa aplicação instalada e configurada com elevated trust. Nos próximos posts, irei explicar como iremos ler o feed RSS, aplicar o Pattern MVVM e utilizar a API do Outlook via COM para criarmos o item no calendário. Até lá.

Breno Ferreira


Permalink | Comentários (1) | Post RSSRSS comment feed