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

Funções de Data e Hora (Delphi)

É muito comum nos depararmos no dia a dia com a necessidade de manipular datas e horas, seja para um calculo de permanência, dias de atraso enfim, é praticamente escapar de alguma situação que necessite desse tipo de controle. Assim como a necessidade e se utilizar algum recurso para manipular as datas e horas de alguma maneira e freqüente, as duvidas de como o faze-lo também é, basta um breve olhar em qualquer fórum especializado e lá está, alguma duvida relacionada, por isso decidi falar um pouco sobre uma unit muito poderosa chamada DateUtils para a manipulação de data e hora, com um grande numero de métodos e classes que facilitam a vida de qualquer um. Alguns exemplos: CompareDate(constA, B: TDateTime): TValueRelationship; Compara apenas a data de dois valores (do tipo TDateTime) retornando: LessThanValue O primeiro valor é menor que o segundo EqualsValue Os valores são iguais GreaterThanValue O primeiro valor é maior que o segundo CompareDateTime(const A, B: TD

Funções de data Oracle

  Com o Oracle é possível obter uma série de resultados a partir de uma ou mais datas, como por exemplo verificar o último dia do mês ou verificar a quantidade de meses entre duas datas, então vamos a alguns exemplos:   Data atual do sistema: SYSDATE Remover meses de uma data: ADD_MONTHS(SYSDATE, -1) Adicionar meses de uma data: ADD_MONTHS(SYSDATE, +1) Buscar o último dia do mês: LAST_DAY(SYSDATE) Primeiro dia do mês: TRUNC(SYSDATE, ‘MONTH’) Quantidade de meses entre duas datas: MONTHS_BETWEEN(SYSDATE, ‘27/07/1982’) Primeiro dia do ano: TRUNC(SYSDATE, ‘YEAR’) Dias da semana: DECODE( TO_NUMBER( TO_CHAR          (SYSDATE, ‘D’) ) ,1, ‘domingo’ ,2, ‘segunda-feira’ ,3, ‘terça-feira’ ,4, ‘quarta-feira’ ,5, ‘quinta-feira’ ,6, ‘sexta-feira’ ,7,’sábado’ )

Como Verificar se um Objeto Existe (Delphi)

Em alguns momentos surge a necessidade de verificar se um determinado objeto existe, ou seja se já foi criado, principalmente quando se trabalha com criação dinâmica em tempo de execução, então vamos ao exemplo: - Vamos criar uma variável, um vetor do tipo caixa de texto: var Minha_caixa : array of TEdit; - Em seguida definir o tamanho desse vetor, no caso será dez: setLength(Minha_caixa, 10) - Agora iremos criar nossa caixa de texto: // lembrando que o vetor inicia em zero // logo o índice final é o tamanho total - 1 for vl_i := 0 to Length(Minha_caixa) -1 do begin Minha_caixa[vl_i] := TEdit.Create(self); with Minha_caixa[vl_i] do begin Parent := Self; Name := 'Caixa_N'+IntToStr(vl_i); Text := 'Esta é a '+IntToStr(vl_i)+' º caixa !'; ReadOnly := true; Height := 21; Width :=