Pular para o conteúdo principal

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

Comentários

  1. cara, vc esta prestando uma grande ajuda. Obrigado. quando vc irá colocar mais informações? estou no aguardo.

    ResponderExcluir
  2. Olá Ailton! Fico feliz que tenha gostado, se tudo der certo em julho eu voto a postar, já tenho uma série de artigos engatilhados.

    ResponderExcluir

Postar um comentário

Obrigado por Participar do programero, fique a vontade para agradecer, retificar, perguntar ou sugerir.

Mais visitadas

Iniciar e Parar Serviços do Windows (Delphi)

Em certas ocasiões nos deparamos com a necessidade de manipular determinadas atividades do SO, como iniciar ou parar um banco de dados, ou qualquer outro serviço que esteja funcionando no momento. Segue abaixo um código que encontrei na Internet para tal finalidade (não me recordo à fonte, assim que eu a encontrar colocarei). Iniciar Serviço: uses WinSvc; // // start service // // return TRUE if successful // // sMachine: //   machine name, ie: \SERVER //   empty = local machine // // sService //   service name, ie: Alerter // function ServiceStart(   sMachine,   sService : string ) : boolean; var   //   // service control   // manager handle   schm,   //   // service handle   schs   : SC_Handle;   //   // service status   ss     : TServiceStatus;   //   // te...

Listar arquivos existentes em diretório (Delphi)

Mostraremos uma maneira simples e prática para listar o conteúdo de um diretório com a opção de incluir nessa listagem os arquivos de seus subdiretórios. No exemplo abaixo temos um Edit para receber o diretório a ser pesquisado um CheckBox para indicar se os subdiretórios entrarão na pesquisa um botão para efetuar a pesquisa e um Memo para listar os arquivos encontrados, no final um Edit que receberá o cálculo final (em bytes) da soma do tamanho dos arquivos. procedure TForm1.Button1Click(Sender: TObject); begin   tamanhoTotal := 0;   memLista.Lines.Clear;   ListarArquivos(edtDiretorio.Text, chkSub.Checked);   Edit1.Text := IntToStr( tamanhoTotal ); end; procedure TForm1.ListarArquivos(Diretorio: string; Sub:Boolean); var   F: TSearchRec;   Ret: Integer;   TempNome: string; begin   Ret := FindFirst(Diretorio+'\*.*', faAnyFile, F);   try     while Ret = 0 do ...

Centralizar Texto em Edit

Como todos sabemos o Edit mantém todo texto digitado a esquerda, o que não fica bem quando o usamos para a entrada de números, pois bem, o exemplo abaixo apresenta uma alternativa para centralizar um determinado valor dentro de um Edit: procedure EditChange(Sender: TObject); var vl_label : TLabel; //variável do tipo Label begin vl_label := TLabel.Create(self); //criamos um label WITH vl_label DO BEGIN Font.Name := TEdit(sender).Font.Name; //pegamos a fonte usada no edit Caption := TEdit(sender).Text; //pegamos o conteúdo do edit SendMessage(TEdit(sender).Handle, EM_SETMARGINS, EC_LEFTMARGIN, (TEdit(sender).Width-vl_label.Width) div 2); //centraliza no label e retorna para o edit END ; vl_label.Free; end ;