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.

 

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 III: COM Interop

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 e como ler o feed RSS dos webcasts no MSDN.

Hoje, irei explicar como iremos podemos acessar recursos disponíveis na máquina do usuário através de interfaces COM.

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

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

O que é COM?

COM, ou Component Object Model, é uma tecnologia desenvolvida pela Microsoft na década de 90 para facilitar o desenvolvimento de componentes (bibliotecas). Esses componentes podem ser usados por vários processos independentes, através de interfaces que abstraem a funcionalidade por debaixo dos panos. Assim, chamadas a objetos COM são feitas sem necessariamente saber-se da implementação, bastando chamar os métodos especificados na interface.

Voce pode pensar em COM como serviços que podem ser chamados (através dessas interfaces) por processos rodando na máquina do usuário. Um método é chamado, que irá fazer alguma tarefa, e devolver, se necessário, alguma resposta.

Obs: note que COM é uma tecnologia presente somente em ambientes Windows. Por isso, quando tentarmos acessar bibliotecas COM em nossas aplicações Silverlight, devemos checar, primeiramente, se estamos rodando fora do browser com Elevated Trust e também se a aplicação está rodando em um ambiente Windows. Para saber mais sobre COM, acesse o artigo na Wikipedia e a documentação na MSDN 

Usando COM no Silverlight 4

Para acessar as interfaces COM disponíveis na máquina do usuário, usamos a classe ComAutomationFactory, que possui métodos para acessar e retornar referências de interfaces COM.

Primeiramente, antes de tentarmos acessar qualquer objeto COM, devemos saber se é possível acessá-la (somente é possível acessar bibliotecas COM se estivermos rodando Out-of-Browser com Elevated Trust e em ambiente Windows). Para isso, a classe ComAutomationFactory possui uma propriedade chamada IsAvailable, que já verifica isso para nós.

Para acessarmos uma referência a uma interface COM, devemos chamar o método CreateObject, passando o ProgrammaticID da biblioteca COM que desejamos acessar. Esse método nos retorna um IDisposable, pois depois de feitas todas as operações necessárias, devemos liberar as referências ao objeto COM, chamando o método Dispose().

Como o Silverlight não tem como saber quais são os métodos e propriedades da interface, não é possível ter um objeto estaticamente tipado, e assim termos o adorado Intellisense no Visual Studio. As variáveis que guardam as referências das interfaces COM deverão ser do tipo Object em VB ou dynamic em C#. Assim, os tipos serão determinados em tempo de execução.

Utilizando a API do Outlook

Sem mais teoria, vamos a prática. No projeto Silverlight, adicione uma classe chamada OutlookApplication. Essa classe irá ter um método, que irá criar um item no calendário do Outlook, e uma propriedade que irá determinar se a aplicação tem as permissões necessárias para fazer COM Interop.

Adicione o seguinte código a classe OutlookApplication:

Code Snippet
  1. public static Boolean IsAvailable { get { return ComAutomationFactory.IsAvailable; } }
  2.  
  3. public static void CreateCalendarItem ( FeedItemModel feedItem )
  4. {
  5.     try
  6.     {
  7.         using ( dynamic outlook = ComAutomationFactory.CreateObject ( ( "Outlook.Application" ) ) )
  8.         {
  9.             dynamic appointment = outlook.CreateItem ( 1 ); //1 - AppointmentItem on calendar. More info: http://msdn.microsoft.com/en-us/library/bb208104.aspx
  10.             appointment.Subject = feedItem.Title;
  11.             appointment.Body = feedItem.Description;
  12.             appointment.Duration = feedItem.Duration;
  13.             appointment.Start = feedItem.Date;
  14.             appointment.End = feedItem.Date.AddMinutes ( feedItem.Duration );
  15.             appointment.Location = "Live Meeting";
  16.             appointment.ReminderSet = true;
  17.             appointment.ReminderMinutesBeforeStart = 15;
  18.             appointment.Save ( );
  19.             appointment.Send ( );
  20.         }
  21.     }
  22.     catch ( Exception )
  23.     {
  24.         throw;
  25.     }
  26. }

Snippet 1

Primeiramente, definimos a propriedade IsAvailable, que verifica se a aplicação possui privilégios para chamar objetos COM.

O método CreateCalendarItem, recebe um objeto que guarda um item do RSS dos Webcasts com as informações sobre título, data, duração, etc…

O objeto outlook, guarda a referência da interface COM. Com esse objeto, podemos chamar os métodos e propriedades expostos pela interface. Note que usamos um bloco using. Com isso garantimos que no final da operação, todos os recursos e memória serão liberados.

Em seguida, chamamos o método CreateItem, que irá criar um objeto referente a um item no calendário do Outlook. Setamos algumas propriedades, como

  • Subject (assunto)
  • Body(descrição)
  • Duration(duração)
  • Start e End (data de início e fim, respectivamente)
  • Location (local)
  • ReminderSet (se um aviso é mostrado ao usuário antes do evento começar)
  • ReminderMinutesBeforeStart (quanto tempo antes do evento começar, o aviso é mostrado ao usuário)

Finalmente, chamamos os métodos Save e Send, que salvam o item no calendário do Outlook.

No próximo post, iremos juntar tudo o que fizemos até agora e aplicar o pattern MVVM utilizando a interface ICommand. Até lá

Breno Ferreira


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

Novidades do Silverlight 4 – Parte II: Ler Feeds RSS

Introdução

No post anterior, 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.

Hoje, irei explicar como fazemos para ler um feed RSS utilizando Linq To XML para lermos o XML retornado pelo feed.

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

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

Lendo Feeds RSS no Silverlight

Feed RSS nada mais é do que conteúdo XML usado para publicar updates em sites, blogs, etc… Todo feed RSS possui uma URL acessível globalmente, que pode ser acessada por algum cliente e que irá dar como resposta esse XML.

Para lermos o RSS, utilizamos a classe WebClient, que possibilita receber a resposta de algum recurso na web, exposto através de uma URL. Com a resposta deste recurso (XML do RSS), utilizamos o Linq To XML para analisar o XML e ler os dados contidos nele.

Para começarmos, adicione uma classe ao projeto Silverlight chamado FeedItemModel. Essa classe irá ser o Model (usando o Pattern MVVM, mas por enquando ignore isso, veremos isso em um próximo post) que irá guardar as informações do Feed.

Como estaremos lendo o feed dos webcasts no MSDN, temos que guardar algumas informações como:

  • Título do Webcast
  • Link para cadastro
  • Data
  • Duração
  • Criador (quem são os palestrantes)
  • Descrição

Na classe FeedItemModel, adiciona as seguintes propriedades, que irão guardar as informações acima:

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

Agora, temos que ler o conteúdo do feed.

Adicione uma classe chamada RssReader. Essa classe irá possuir um método que faz o download do XML do feed.

Adicione a classe RssReader o seguinte trecho de código:

Code Snippet
  1. public void ReadRssFeedAsync ( Uri feedUri )
  2.         {
  3.             WebClient client = new WebClient ( );
  4.             client.DownloadStringCompleted += new DownloadStringCompletedEventHandler ( client_DownloadStringCompleted );
  5.             client.DownloadStringAsync ( feedUri );
  6.         }
  7.  
  8.         private void client_DownloadStringCompleted ( object sender, DownloadStringCompletedEventArgs e )
  9.         {
  10.             if ( e.Error == null )
  11.             {
  12.                 XDocument doc = XDocument.Parse ( e.Result );
  13.  
  14.                 var items = from item in doc.Descendants ( "item" )
  15.                             select new FeedItemModel ( )
  16.                             {
  17.                                 Title = item.Element ( "title" ).Value,
  18.                                 Link = new Uri ( item.Element ( "link" ).Value.ToString ( ) ),
  19.                                 Date = ConvertToDateTime( item.Element ( "pubDate" ).Value ),
  20.                                 Creator = item.Element ( XName.Get("creator", "http://purl.org/dc/elements/1.1/") ).Value,
  21.                                 Description = ReplaceHTMLChars(item.Element ( "description" ).Value),
  22.                                 Duration = GetDurationFromDescriptionn(item.Element("description").Value),
  23.                             };
  24.  
  25.                 if ( this.RssFeedReadCompleted != null )
  26.                     RssFeedReadCompleted ( this, new RssFeedReadCompletedEventArgs ( ) { Feeds = items } );
  27.             }
  28.         }

Snippet 2

No método ReadRssFeedAsync, recebemos a URI do feed como parâmetro (no caso do feed dos webcasts do MSDN, a URL é: 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).

Criamos um objeto do tipo WebClient e chamamos o método DownloadStringAsync, que irá baixar o XML do feed. É importante saber que no Silverlight, qualquer chamada a recursos remotos via HTTP é feita de forma assíncrona, por isso, antes de chamarmos o método DownloadStringAsync, temos que associar o evento DownloadStringCompleted a um método (nesse caso, client_DownloadStringCompleted), que será chamado quando o download terminar.

No método client_DownloadStringCompleted, checamos se houve algum erro no download (if e.Error == null). Se não houve erro, então criamos um XDocument com o conteúdo baixado (e.Result). Então, utilizamos uma Linq query para pegarmos todos os elementos com o nome “item” (doc.Descendants(“item”)) e pegarmos seus elementos filhos, que trazem as informações sobre o Webcast (esses elementos são: title, link, pubDate, …).

Na linha 20, temos que usar o método XName.Get, pois no XML do feed, o elemento “creator” faz parte do XML Namespace “http://purl.org/dc/elements/1.1/” (se voce olhar no conteúdo XML, voce verá que o elemento creator estará assim “dc:creator” e no início do XML, é adicionado o XML namespace dc que aponta para “http://purl.org/dc/elements/1.1/”).

Obs: os métodos “ConvertToDateTime”, “ReplaceHTMLChars” e “GetDurationFromDescriptionn” somente fazem algumas operações auxiliares como limpar caracteres inválidos e fazer algumas operações no texto para pegar a duração do Webcast. Voce pode ver o que essas funções fazem se voce baixar o código da aplicação, no início deste post.

Essa Linq query irá retornar um IEnumerable de FeedItemModel. Mas, como a operação é feita de maneira assíncrona, temos que informar a quem chamou a função ReadRssFeedAsync, que a operação terminou e os resultados foram obtidos. Para isso, criamos um evento que será chamado quando a operação completar (linha 26), passando a coleção de FeedItemModel.

Neste post vimos como ler o Feed RSS com os Webcasts do MSDN. Nos próximos posts, iremos ver como criar um item no calendário do Outlook com os dados do Webcast e juntar todas as funcionalidades na aplicação usando o Pattern MVVM (Model-View-ViewModel)


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

Usando o Silverlight WebBrowser Control

Introdução

No Silverlight 4, foi incluído um controle bem interessante chamado WebBrowser. Esse controle é usado para apresentar conteúdo HTML. Note que esse controle funciona somente em aplicações rodando fora do browser. Isso por que não faria muito sentido usar este controle em uma aplicação rodando dentro do Browser, já que é possível interagir com o navegador (para saber mais, leia sobre HtmlPage e HtmlDocument).

Voce pode baixar o código da aplicação desenvolvida para este tutorial no link abaixo:

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

Configurando Out-of-Browser

Primeiramente, crie uma nova aplicação Silverlight no Visual Studio. Como o controle WebBrowser só funciona para aplicações Out-of-Browser, temos que configurar nossa aplicação para funcionar fora do navegador. Para fazer isso, clique com o botão direito no projeto Silverlight e vá em Propriedades.

image

Feito isso, na guia “Silverlight” marque a opção “Enable running application out of the browser”.

image 

Agora, temos que ter certeza que a aplicação irá rodar fora do browser. Para fazermos isso, temos que ter duas “telas” distintas. Uma para quando a aplicação está rodando no browser, que irá pedir para o usuário instala-la em sua máquina, e outra, que irá ter o controle WebBrowser, quando a aplicação estiver fora do browser.

Clique com o botão direito no projeto Silverlight, vá em “Add” > “New Item” e escolha “Silverlight Child Window”.

image

Dê o nome de InstalaçãoWindow e clique em “Add”. Essa janela irá pedir ao usuário que instale a aplicação em sua máquina.

Adicione o seguinte XAML ao arquivo InstalacaoWindow.xaml:

Code Snippet
  1. <controls:ChildWindow x:Class="SilverlightBrowser.InstalacaoWindow"
  2.            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.            xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
  5.            Width="400" Height="110"
  6.            Title="InstalacaoWindow">
  7.     <Grid x:Name="LayoutRoot" Margin="2">
  8.         <Grid.RowDefinitions>
  9.             <RowDefinition />
  10.             <RowDefinition Height="Auto" />
  11.         </Grid.RowDefinitions>
  12.  
  13.         <TextBlock x:Name="notificacaoTxt" Text="Esta aplicação precisa rodar Out-of-Browser" HorizontalAlignment="Center" Margin="10" />
  14.         <Button x:Name="CancelButton" Content="Cancelar" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
  15.         <Button x:Name="OKButton" Content="Instalar" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
  16.     </Grid>
  17. </controls:ChildWindow>

Snippet 1

Nesse XAML, criamos um um botão (OKButton) que irá verificar se a aplicação está instalada na máquina do usuário. Caso não esteja, irá instala-la.

No arquivo InstalacaoWindow.xaml.cs, adicione o seguinte código:

Code Snippet
  1. private void OKButton_Click ( object sender, RoutedEventArgs e )
  2. {
  3.     if ( Application.Current.InstallState == InstallState.NotInstalled )
  4.         Application.Current.Install ( );
  5.     else
  6.         MessageBox.Show ( "Aplicação já instalada" );
  7.     this.DialogResult = true;
  8. }

 

Snippet 2

Na linha 3, checamos o InstallState da aplicação, que nos diz se a aplicação está ou não instalada na máquina do usuário. Caso, não esteja (NotInstalled), chamamos o método Install(), que irá mostrar ao usuário o prompt de instalação.

image

Clique em OK. Agora o runtime do Silverlight irá instalar a aplicação na máquina do usuário, criando atalhos (caso o usuário marque as CheckBoxes) no Menu Iniciar e na Área de Trabalho.

Agora vamos configurar o Visual Studio para executar a aplicação instalada, e não a página que hospeda o controle Silverlight.

Vá nas propriedades do projeto Silverlight, na guia Debug, em “Start Action”, marque a opção “Instaled out-of-browser application”.

image

Em seguida, clique com o botão direito no projeto Silverlight, e marque a opção “Set as StartUp Project”.

image

WebBrowser Control

Iremos agora criar o controle que irá mostrar o WebBrowser. Adicione um novo UserControl a solução chamado BrowserControl.

No arquivo BrowserControl.xaml, adicione o seguinte XAML:

Code Snippet
  1. <UserControl x:Class="SilverlightBrowser.BrowserControl"
  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.     mc:Ignorable="d">
  7.  
  8.     <Grid x:Name="LayoutRoot" Background="White">
  9.         <Grid.RowDefinitions>
  10.             <RowDefinition Height="23" />
  11.             <RowDefinition Height="*" />
  12.         </Grid.RowDefinitions>
  13.         <Grid.ColumnDefinitions>
  14.             <ColumnDefinition Width="*" />
  15.             <ColumnDefinition Width="25" />
  16.         </Grid.ColumnDefinitions>
  17.         
  18.         <TextBox x:Name="urlTxt" Text="http://www.bing.com" />
  19.         <Button x:Name="navBtn" Content="Go" Grid.Column="1" Click="navBtn_Click" />
  20.         
  21.         <WebBrowser x:Name="browser" Grid.Row="1" Grid.ColumnSpan="2" Width="1000" Height="700" />
  22.     </Grid>
  23. </UserControl>

Snippet 3

Neste snippet, criamos uma TextBox que onde o usuário irá digitar a URL da página que ele deseja visitar, um botão que irá navegar para a página desejada.

Na linha 21, criamos o controle WebBrowser, demos a ele um nome (browser) e setamos sua largura, altura e sua posição no Grid.

No arquivo BrowserControl.xaml.cs, edite o EventHandler navBtn_Click, adicionando o seguinte código:

Code Snippet
  1. private void navBtn_Click ( object sender, RoutedEventArgs e )
  2. {           
  3.     String html = String.Empty;
  4.     if ( urlTxt.Text.StartsWith ( "http://" ) )
  5.         html = "<iframe src=\"" + this.urlTxt.Text + "\" style=\"width:100%;height:100%;\" />";
  6.     else
  7.         html = this.urlTxt.Text;
  8.  
  9.     this.browser.NavigateToString ( html );
  10. }

Snippet 4

O controle WebBrowser possui 2 métodos que podem ser usados para mostrar o conteúdo HTML.

  • Navigate(URI source): esse método recebe uma URI que irá apontar para o site que deseja-se mostrar no WebBrowser. Entretanto, há um porém. Devido a restrições de segurança, o WebBrowser só renderiza páginas no mesmo domínio da sua aplicação. Uma maneira de contornar essa situação é usando o método abaixo.
  • NavigateToString(String text): esse método recebe como parâmetro uma string com qualquer conteúdo HTML e o WebBrowser control irá renderizá-lo. Então podemos usar este método para mostrar páginas que sejam de outro domínio que não seja o nosso. Basta criamos um <iframe> e setarmos o atributo src para a página que desejamos abrir.

Na linha 4, verificamos se o usuário está tentando abrir uma página, verificando se o enderço começa com “http://”. Se sim, criamos o <iframe> e setamos o atributo src com o enderço digitado pelo usuário.

O usuário também pode digitar qualquer conteúdo HTML na TextBox que o WebBrowser irá interpretar e  rederizar na tela.

 

Aperte F5, e execute a aplicação.

Na imagem abaixo, vemos o WebBrowser mostrando a página do Bing.

image

E na imagem abaixo, vemos o WebBrowser mostrando um conteúdo HTML referente a um vídeo do YouTube.

image


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