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

Aplicação Flask usando Nginx e Gunicorn

Aplicação Flask usando Nginx e Gunicorn Se você já desenvolveu uma aplicação Flask básica, sabe que o servidor de desenvolvimento embutido não é ideal para produção. Ele não é projetado para lidar com altos volumes de tráfego ou conexões simultâneas. Para tornar sua aplicação Flask mais robusta e pronta para produção, podemos usar o Gunicorn como servidor de aplicação e o Nginx como proxy reverso. Neste artigo, vamos adaptar o exemplo anterior ( Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker ) para incluir o Nginx e o Gunicorn. O que são Nginx e Gunicorn? Gunicorn O Gunicorn (Green Unicorn) é um servidor de aplicação WSGI que roda aplicações Python como o Flask. Ele é eficiente e simples de configurar, lidando com múltiplas requisições ao mesmo tempo, algo que o servidor embutido do Flask não faz bem. Nginx O Nginx é um servidor web que atua como um proxy reverso. Ele recebe requisições HTTP e as encaminha ao Gunicorn. Além disso, o Nginx pode: Servir arquivos ...

Criando sua Primeira Aplicação Web com Python e Docker

  Criando sua Primeira Aplicação Web com Python e Docker Hoje vamos fazer algo prático: criar uma aplicação web simples em Python usando Flask e executá-la dentro de um contêiner Docker. Se você não sabe exatamente o que é Docker ou Flask, não se preocupe! Vou explicar tudo de forma simples para que você consiga acompanhar sem problemas. O que é Docker? Docker é uma ferramenta que permite empacotar aplicações e suas dependências em contêineres, garantindo que elas funcionem da mesma forma em qualquer ambiente. Em outras palavras, com o Docker, você cria um ambiente isolado e padronizado para rodar suas aplicações. Como instalar o Docker Acesse o site oficial do Docker . Baixe e instale a versão apropriada para o seu sistema operacional (Windows, macOS ou Linux). Após a instalação, verifique se está tudo funcionando abrindo um terminal e executando: docker --version Se o Docker estiver instalado corretamente, ele vai exibir a versão instalada. O que é Flask? Flask é um m...

Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker

Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker Neste guia, vamos criar uma aplicação básica que acessa um banco de dados PostgreSQL e realiza operações CRUD (Create, Read, Update, Delete). Vamos usar Flask e executar tudo com Docker. Sem estilos ou extras, apenas o essencial. Estrutura do Projeto crud-app/ |-- app/ | |-- app.py | |-- templates/ | | |-- index.html | | |-- edit.html |-- Dockerfile |-- requirements.txt |-- docker-compose.yml Passo 1: Dependências Crie um arquivo requirements.txt com as seguintes linhas: Flask==2.2.2 Flask-SQLAlchemy==3.0.2 psycopg2-binary==2.9.3 Werkzeug==2.2.2 Passo 2: Aplicação Flask Arquivo app/app.py : from flask import Flask, render_template, request, redirect, url_for from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # Configuração do banco de dados app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@db:5432/crud_db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db...