Pesquisar no Programero

sábado, 23 de janeiro de 2010

Iniciando com o Silverlight: Parte 2 – Definindo o layout e a navegação

 

Essa é a segunda parte de uma série  de posts que pretendo publicar, elas foram inicialmente feitas por Tim Heuer do Method of failed. Irei traduzir seus artigos e tentarei simplificar ao máximo esse ótimo trabalho.

Entender como funciona a estrutura de layout do XAML é uma das coisas mais importantes no desenvolvimento de aplicações com o Silverlight. Apesar de ser conceitualmente semelhante ao que encontramos no desenvolvimento padrão para web, desenvolver com o Silverlight tem suas particularidades.

Entendendo as opções de layout

O Silverlight possui um sistema bem flexível para a construção de interfaces, existindo modelos de layout que suportam estilos dinâmicos e absolutos. Os mais utilizados são:

  • Canvas
  • StackPanel
  • Grid

Canvas

O Canvas é o layout mais básico que permite posicionar elementos de forma absoluta, usando coordenadas. Todos os objetos que estiverem dentro do Canvas “herdam” propriedade de posicionamento em relação a ele, veja o exemplo:

   1: <Canvas>



   2:  



   3: <Button Canvas.Top="50" Canvas.Left="50" Content="Button 1" FontSize="18" Width="150" Height="45" />



   4:  



   5: <Button Canvas.Top="150" Canvas.Left="20" Content="Button 2" FontSize="18" Width="150" Height="45" />



   6:  



   7: <Button Canvas.Top="70" Canvas.Left="80" Canvas.ZIndex="99" Content="Button 3" FontSize="18" Width="150" Height="45" />



   8:  



   9: </Canvas>



  10:  




Esse é o resultado:



Canvas layout



 



StackPanel



O layout StackPanel organiza os elementos em “pilhas” verticais ou horizontais (vertical por default), veja o exemplo:





   1: <StackPanel>



   2:  



   3: <Button Margin="10" Content="Button 1" FontSize="18" Width="150" Height="45" />



   4:  



   5: <Button Margin="10" Content="Button 2" FontSize="18" Width="150" Height="45" />



   6:  



   7: <Button Margin="10" Content="Button 3" FontSize="18" Width="150" Height="45" />



   8:  



   9: </StackPanel>



  10:  




Esse é o resultado:


StackPanel vertical

Se alterarmos a orientação para horizontal:





   1: <StackPanel Orientation="Horizontal">



   2:  



   3: <Button Margin="10" Content="Button 1" FontSize="18" Width="150" Height="45" />



   4:  



   5: <Button Margin="10" Content="Button 2" FontSize="18" Width="150" Height="45" />



   6:  



   7: <Button Margin="10" Content="Button 3" FontSize="18" Width="150" Height="45" />



   8:  



   9: </StackPanel>



  10:  




Teremos esse resultado:



StackPanel horizontal



 



Grid



De uma maneira geral o layout em grid é um dos mais flexíveis, funciona de maneira idêntica a uma construção com tabelas (<table>),  sem a necessidade que o código fique dentro de tags como <tr> e <td>, observemos o código:





   1: <Grid ShowGridLines="True">



   2:  



   3: <Grid.RowDefinitions>



   4:  



   5: <RowDefinition Height="60" />



   6:  



   7: <RowDefinition Height="60" />



   8:  



   9: <RowDefinition Height="60" />



  10:  



  11:  



  12: </Grid.RowDefinitions> 



  13:  



  14: <Grid.ColumnDefinitions>



  15:  



  16: <ColumnDefinition Width="175" />



  17:  



  18: <ColumnDefinition Width="175" />



  19:  



  20: <ColumnDefinition Width="175" />



  21:  



  22: </Grid.ColumnDefinitions> 



  23:  



  24:  



  25: <Button Grid.Column="0" Grid.Row="0" Content="Button 1" FontSize="18" Width="150" Height="45" />



  26:  



  27: <Button Grid.Column="2" Grid.Row="0" Margin="10" Content="Button 2" FontSize="18" Width="150" Height="45" />



  28:  



  29: <Button Grid.Column="1" Grid.Row="2" Margin="10" Content="Button 3" FontSize="18" Width="150" Height="45" />



  30:  



  31: </Grid>



  32:  




O resultado:





Podemos notar que as definições de coluna e linha no inicio do código definem como essa nossa “tabela” será construída, nesse caso três linhas por três colunas.



Construindo nossa Aplicação Twitter



Iremos dar inicio a construção da aplicação, ela deverá se como a figura abaixo:



Twitter app mockup



Percebam que haverá um lugar para o usuário entrar com o termo a ser pesquisado e que os resultados serão mostrados em uma espécie de lista. Teremos uma área de navegação para visualizar o histórico e estatísticas.



O template escolhido resuma em boa parte nossos esforços, em MainPage.xaml iremos editar a linha 29 removendo o logo e iremos alterar o nome da aplicação em ApplicationNameTextBlock para “Twitter Search Monitor”.



Vamos criar uma nova página Silverlight e chama-lá de Search.xaml, clique com o direito em Views, novo item, Silverlight templates:



Add Silverlight Page dialog



 



FrameWork de navegação Siverlight



Antes de prosseguir com a construção de nossa aplicação vamos falar um pouco sobre o FrameWork de navegação do Silverlight, no artigo anterior iniciamos um novo projeto com o template de navegação (Silverlight Navigation Application), como default esse template possui as páginas MainPage.xaml e duas visões (Home e About). Vamos falar sobre três partes fundamentais: UriMapper, Frame e Page.



UriMapper



O UriMapper é um elemento que simplifica endereços, mapeia rotas para simplificar as chamadas a páginas, veja o código abaixo:









   1: <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"                     Source="/Home" Navigated="ContentFrame_Navigated"                     NavigationFailed="ContentFrame_NavigationFailed">



   2:  



   3: <navigation:Frame.UriMapper>



   4:  



   5: <uriMapper:UriMapper>



   6:  



   7: <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>



   8:  



   9: <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>



  10:  



  11: </uriMapper:UriMapper>



  12:  



  13: </navigation:Frame.UriMapper>



  14:  



  15: </navigation:Frame>



  16:  




O mapeamento definido pelo código indica que todos os endereços solicitados serão verificados na pasta Views, ou seja, será necessário apenas “nome_do_servidor/Pagina” ao invés de “nome_do_servidor/Views/Pagina.xaml”.



Frame



O Frame é a área de navegação, para quem já desenvolveu em ASP .NET podemos compara-lo ao ContentPlaceHolder.



Page



São basicamente o conteúdo mostrado dentro dos Frames. Iremos considerar nossas Views como nossas páginas, elas sempre aparecerão dentro do Frame, localizado em nossa MainPage.



Para aprender mais sobre navegação assistam a esse vídeo:





 



Criando o layout de nossa página de busca



A essa altura algumas pessoas devem estar se perguntado para que serve o {StaticResource XXXXXXXX} que tanto aparece nos códigos desse template, deixaremos essa explicação para posts futuros.



Nossa página Search.xaml deverá possuir um TextBox (SearchTerm) para a entrada do termo a ser consultado, um Button (SearchButton) para iniciar o processo e um DataGrid (SearchResults) para mostrar o resultado, o código deverá ser como o apresentado abaixo:





   1: <navigation:Page                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



   2:  



   3: mc:Ignorable="d" 



   4:  



   5: xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"



   6:  



   7: xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="TwitterSearchMonitor.Views.Search"



   8:  



   9: d:DesignWidth="640" d:DesignHeight="480"



  10:  



  11: Title="Twitter Search Page">



  12:  



  13: <Grid x:Name="LayoutRoot">



  14:  



  15: <Grid.RowDefinitions>



  16:  



  17: <RowDefinition Height="32"/>



  18:  



  19: <RowDefinition/>



  20:  



  21: </Grid.RowDefinitions>



  22:  



  23: <StackPanel HorizontalAlignment="Left" Margin="0,-32,0,0" VerticalAlignment="Top" Grid.Row="1" Orientation="Horizontal">



  24:  



  25: <TextBox x:Name="SearchTerm" FontSize="14.667" Margin="0,0,10,0" Width="275" TextWrapping="Wrap"/>



  26:  



  27: <Button x:Name="SearchButton" Width="75" Content="SEARCH"/>



  28:  



  29: </StackPanel>



  30:  



  31: <data:DataGrid x:Name="SearchResults" Margin="0,8,0,0" Grid.Row="1"/>



  32:  



  33: </Grid>



  34:  



  35: </navigation:Page>



  36:  




Vamos aproveitar para tornar nossa página de busca a “Home” do projeto:





   1: <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}" 



   2:  



   3: Source="/Search" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">



   4:  



   5: <navigation:Frame.UriMapper>



   6:  



   7: <uriMapper:UriMapper>



   8:  



   9: <uriMapper:UriMapping Uri="" MappedUri="/Views/Search.xaml"/>



  10:  



  11: <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>



  12:  



  13: </uriMapper:UriMapper>



  14:  



  15: </navigation:Frame.UriMapper>



  16:  



  17: </navigation:Frame>



  18:  




Como não iremos mais utilizar a página Home.xaml podemos exclui-la. Aproveitando criaremos uma nova página chamado History.xaml (a exemplo da página Search.xaml, por enquanto sem conteúdo em especial). Para finalizar vamos acertar nossa barra de navegação:





   1: <Border x:Name="LinksBorder" Style="{StaticResource LinksBorderStyle}">



   2:  



   3: <StackPanel x:Name="LinksStackPanel" Style="{StaticResource LinksStackPanelStyle}">    



   4:  



   5: <HyperlinkButton x:Name="Link1" Style="{StaticResource LinkStyle}"                              NavigateUri="/Search" TargetName="ContentFrame" Content="home"/>                             



   6:  



   7: <Rectangle x:Name="Divider1" Style="{StaticResource DividerStyle}"/>



   8:  



   9: <HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}"                             NavigateUri="/History" TargetName="ContentFrame" Content="history"/>                            



  10:  



  11: <Rectangle x:Name="Divider2" Style="{StaticResource DividerStyle}"/>    



  12:  



  13: <HyperlinkButton x:Name="Link3" Style="{StaticResource LinkStyle}"                             NavigateUri="/About" TargetName="ContentFrame" Content="about"/>    



  14:  



  15: </StackPanel>



  16:  



  17: </Border>



  18:  




Nosso resultado final:



Final layout rendered



 



Considerações



Nosso pequeno projeto de teste começou a tomar forma, nos próximos posts iremos implementar suas funcionalidades.



Aguardem o próximos posts e fiquem a vontade para sugerir e comentar.



Só para finalizar vamos prestigiar esse ótimo trabalho de Tim Heuer, autor dessa série de artigos de introdução ao Silverlight.



Parte 1Parte 2



Fonte



Method ~of ~failed