Compartilhar via


Capítulo 3: Controles e XAML

 

Introdução
Capítulo 1: o modelo de aplicativo "Longhorn"
Capítulo 2: Criando um aplicativo "Longhorn"

Capítulo 3: Controles e XAML

Refatoração Brent
Wise Owl Consulting

Dezembro de 2003

Sumário

Elementos XAML
Painéis XAML
Controles
Recursos e estilos
Elementos gráficos e animações
Serviços de Documentos
Resumo

Como você viu no Capítulo 2, os aplicativos de plataforma Longhorn normalmente consistem em um objeto Application e um conjunto de páginas de interface do usuário que você escreve em uma linguagem de marcação declarativa chamada XAML.

O objeto Application é um singleton e persiste durante todo o tempo de vida do aplicativo. Ele permite que a lógica do aplicativo manipule eventos de nível superior e compartilhe código e estado entre páginas. O objeto Application também determina se o aplicativo é um aplicativo de janela única ou um aplicativo de navegação.

Normalmente, você escreve cada página de interface do usuário usando um dialeto de XML chamado XAML (Extensible Application Markup Language). Cada página consiste em elementos XAML, nós de texto e outros componentes organizados em uma árvore hierárquica. A relação hierárquica desses componentes determina como a página é renderizada e se comporta.

Você também pode considerar uma página XAML como uma descrição de um modelo de objeto. Quando o runtime cria a página, ele cria uma instância de cada um dos elementos e nós descritos no documento XAML e cria um modelo de objeto equivalente na memória. Você pode manipular esse modelo de objeto programaticamente, por exemplo, você pode adicionar e remover elementos e nós para fazer com que a página seja renderizada e se comporte de forma diferente.

Fundamentalmente, uma página XAML descreve as classes que o runtime deve criar, os valores de propriedade e os manipuladores de eventos para as instâncias das classes e uma hierarquia de modelo de objeto, ou seja, qual instância é o pai de outra instância.

Todos os documentos XAML são documentos XML bem formados que usam um conjunto definido de nomes de elementos. Portanto, todas as regras relativas à formação de documentos XML bem formados se aplicam igualmente a documentos XAML. Por exemplo, o documento deve conter um único elemento raiz; todos os nomes de elemento diferenciam maiúsculas de minúsculas; uma definição de elemento não pode sobrepor outra definição de elemento, mas deve contê-la inteiramente e assim por diante. Se você não estiver familiarizado com a sintaxe XML, agora é um excelente momento para aprender.

Elementos XAML

Cada página XAML contém um ou mais elementos que controlam o layout e o comportamento da página. Você organiza esses elementos hierarquicamente em uma árvore. Cada elemento tem apenas um pai. Os elementos geralmente podem ter qualquer número de elementos filho. No entanto, alguns tipos de elementos, por exemplo, Scrollbar, não têm filhos; e outros tipos de elementos, por exemplo, Border, podem ter um único elemento filho.

Cada nome de elemento corresponde ao nome de uma classe gerenciada. Adicionar um elemento a um documento XAML faz com que o runtime crie uma instância da classe correspondente. Por exemplo, a marcação a seguir representa um elemento DockPanel raiz que tem um único elemento Table filho. O elemento Table contém três elementos Row filho. Cada elemento Row contém três filhos e alguns deles têm nós de texto filho.

<Border xmlns="https://schemas.microsoft.com/2003/xaml" 
        Background="BlanchedAlmond">
  <DockPanel>
    <Table> 
      <Body>
        <Row>
          <Cell><Button/></Cell>
          <Cell><Text>Item</Text></Cell>
          <Cell><Text>Price</Text></Cell>
        </Row>
        <Row>
          <Cell><CheckBox Checked="true"/></Cell>
          <Cell><TextBox Height="50">Nissan 350Z</TextBox></Cell>
          <Cell><TextBox Height="50">29.95</TextBox></Cell>
        </Row>
        <Row>
          <Cell><CheckBox/></Cell>
          <Cell><TextBox Height="50">Porsche Boxster</TextBox></Cell>
          <Cell><TextBox Height="50">9.95</TextBox></Cell>
        </Row>
      </Body>
    </Table>

  </DockPanel>
</Border>

Este documento XAML cria uma hierarquia de objetos, conforme mostrado na Figura 3-1 e a exibição mostrada na Figura 3-2.

Figura 3-1. Um exemplo de modelo de objeto de página XAML

Clique aqui para obter uma imagem maior

Figura 3-2. A exibição do XAML anterior (clique para uma imagem maior)

Você pode acessar grande parte da funcionalidade desses objetos usando apenas marcação. Usando apenas a marcação, você pode fazer qualquer um dos seguintes procedimentos:

  • Descrever um conjunto hierárquico de objetos que o runtime criará uma instância
  • Definir propriedades de objeto como valores conhecidos estaticamente
  • Definir propriedades de objeto como valores recuperados de uma fonte de dados
  • Fazer com que os valores de propriedade alterados sejam armazenados novamente na fonte de dados
  • Alterar repetidamente o valor de uma propriedade ao longo do tempo
  • Associar um manipulador de eventos ao evento de um objeto

No entanto, embora você possa criar algumas interfaces de usuário incríveis usando apenas marcação, você também pode acessar a funcionalidade de um elemento programaticamente usando o modelo de objeto XAML. O modelo de objeto permite manipular todos os aspectos dos elementos em uma página. Na verdade, ele fornece recursos adicionais que não são acessíveis por meio do XAML.

Cada elemento XAML deriva de System.Windows.UIElement ou System.Windows.ContentElement e, portanto, todos os elementos possuem uma série de recursos comuns. Os elementos podem ser agrupados nas quatro categorias básicas a seguir:

  • Os controles derivam de System.Windows.Control e lidam com a interação do usuário.
  • Os painéis são controles especializados que derivam de System.Windows.Panel e manipulam o layout da página e atuam como contêineres para elementos.
  • Os elementos de formatação de texto derivam de System.Windows.TextElement e manipulam a formatação de texto e a estrutura do documento.
  • As formas lidam com formas gráficas vetoriais.

Painéis XAML

Normalmente, uma página XAML começa com um elemento de painel. O painel é um contêiner para o conteúdo de uma página e controla o posicionamento e a renderização desse conteúdo. Na verdade, quando você exibe qualquer coisa usando XAML, um painel sempre está envolvido, embora às vezes seja implícito em vez de um que você descreva explicitamente. Um painel pode conter outros painéis, permitindo que você particione a superfície de exibição em regiões, cada uma controlada por seu painel.

Há seis classes internas do Painel na plataforma Longhorn:

  • Um Canvas posiciona cada elemento filho explicitamente usando coordenadas relativas à área canvas .
  • Um DockPanel coloca seus filhos na parte superior, inferior, esquerda, direita ou centro do painel. Quando você atribui vários filhos à mesma área, um DockPanel os organiza horizontalmente ou verticalmente nessa área.
  • Um FlowPanel organiza seus elementos filho de acordo com suas propriedades de quebra de linha e alinhamento. Quando o conteúdo exceder o comprimento de uma única linha, o painel quebrará linhas, encapsulará linhas e alinhará o conteúdo adequadamente.
  • Um TextPanel renderiza várias linhas de texto em vários formatos de texto. Normalmente, você o usará somente quando precisar de um layout de texto complexo. Para a maioria dos casos, você usará o elemento Text leve para suporte de texto básico.
  • Um GridPanel é um elemento leve que organiza seus elementos filho em linhas e colunas que formam uma grade. É útil para criar tabelas simples, mas tem recursos limitados. Você usaria o controle Tabela para layout de tabela complexo.
  • Um FixedPanel posiciona seus elementos filho em uma página de layout fixa. Os elementos em páginas de layout fixas sempre têm o mesmo posicionamento e paginação, independentemente da resolução do dispositivo ou do tamanho da janela.

Geralmente, esses painéis fornecerão funcionalidade suficiente para a maioria dos desenvolvedores. No entanto, você também pode criar suas próprias classes de painel que posicionam e exibem conteúdo de maneira especializada.

Tela

O painel Tela fornece uma flexibilidade considerável em relação ao posicionamento e à organização de elementos na tela. Ele permite especificar o local para cada elemento filho e, quando os elementos se sobrepõem, você pode especificar a ordem na qual a tela desenha os elementos sobrepostos alterando a ordem em que os elementos aparecem na marcação.

A marcação a seguir produz três elementos gráficos sobrepostos, como você vê na Figura 3-1: um retângulo verde com uma borda laranja, uma elipse amarela translúcida com uma borda azul e um texto centralizado no retângulo. (O pensamento de nunca mais escrever um manipulador WM_PAINT para desenhar coisas como esta traz lágrimas aos meus olhos . . . lágrimas de alegria eu apresso para adicionar!) A estrutura desenha as formas na ordem apresentada, de modo que o texto aparece sobre o retângulo.

<Canvas xmlns="https://schemas.microsoft.com/2003/xaml" >
  <Rectangle 
    Fill="#33CC66"
    Width="2in"       Height="1in"
    Canvas.Top="25"          Canvas.Left="50"
    StrokeThickness="6px" Stroke="Orange" />

  <Ellipse         
    Fill="yellow"
    CenterX="1.5in"    CenterY="1.1in"
    RadiusX=".5in"     RadiusY="1in"
    StrokeThickness="4px"  Stroke="Blue" />

   <Text
    Canvas.Top="50" Canvas.Left="60" Foreground="#000000"
    FontWeight="Bold" FontFamily="Arial"
    FontStyle="Normal" FontSize="25">Hello Shapes!</Text>

</Canvas>

Figura 3-3. Um exemplo usando o painel Tela

DockPanel

O painel DockPanel organiza elementos filho horizontal ou verticalmente, em relação uns aos outros. A classe DockPanel examina a propriedade Dock de cada elemento filho para determinar como alinhar o elemento ao longo das bordas do painel. Você pode definir a propriedade Dock como um dos cinco valores: Superior, Inferior, Esquerda, Direita ou Preenchimento.

Por exemplo, um painel alinha o primeiro elemento filho com sua propriedade Dock igual a Top na borda superior do painel. Em seguida, o painel alinha o próximo elemento filho com sua propriedade Dock igual a Top logo abaixo do elemento anterior. O painel alinha de forma semelhante os elementos filho com a propriedade Dock definida como Inferior, Esquerda ou Direita. Definir a propriedade Dock do último elemento filho como Fill faz com que ele ocupe todo o espaço restante no DockPanel. Nunca siga um elemento Dock="Fill" com outros elementos porque os elementos subsequentes não estarão visíveis. O valor padrão da propriedade Dock é Left, portanto, quando você não define a propriedade Dock para um elemento, ela é empilhada horizontalmente à esquerda.

A propriedade Dock é uma propriedade anexada, ela é definida pela classe DockPanel , mas você a define em um elemento filho como este:

<child DockPanel.Dock="Top"/>

Ou no código:

DockPanel.SetDock(child, Dock.Top)

A marcação a seguir usa um DockPanel e cinco painéis canvas para criar uma interface do usuário comumente vista. O DockPanel alinha as duas primeiras telas na parte superior do DockPanel. Ele alinha a terceira tela à borda inferior do DockPanel, a quarta contra a borda esquerda e a quinta tela preenche o espaço restante. Você pode colocar um menu no painel superior e uma barra de ferramentas no painel logo abaixo do menu. Essa decisão deixa o painel esquerdo para uma exibição de árvore, o painel inferior de uma barra de status e o painel restante para o modo de exibição de item selecionado detalhado, como você pode ver na Figura 3-4.

<Border xmlns="https://schemas.microsoft.com/2003/xaml" 
Background="White">
  <DockPanel>
          <Border Width="500" DockPanel.Dock="Top" 
BorderThickness="2,2,2,2" BorderBrush="Black" Background="#87ceeb" >
              <Text>Dock = "Top"</Text>
          </Border>
          <Border Width="500" DockPanel.Dock="Top" 
BorderThickness="2,2,2,2" BorderBrush="Black" Background="#87ceeb" >
            <Text>Dock = "Top"</Text>
          </Border>
          <Border Width="500" DockPanel.Dock="Bottom" 
BorderThickness="2,2,2,2"
                  BorderBrush="Black" Background="#ffff99" >
            <Text>Dock = "Bottom"</Text>
          </Border>
          <Border Width="200" DockPanel.Dock="Left" 
BorderThickness="2,2,2,2" BorderBrush="Black" Background="#98fb98" >
            <Text>Dock = "Left"</Text>
          </Border>
          <Border Width="300" DockPanel.Dock="Fill" 
BorderThickness="2,2,2,2" BorderBrush="Black" Background="White" >
            <Text>Dock = "Fill"</Text>
          </Border>
  </DockPanel>
</Border>

Figura 3-4. Um exemplo usando o painel DockPanel

FlowPanel

O painel FlowPanel fornece uma série de recursos de layout automático e permite apresentações complexas de texto e gráficos. Você define o tamanho do painel usando suas propriedades Width e Height . Em seguida, o painel exibe seus elementos filho de uma maneira que melhor usa o espaço do painel, encapsulando e alinhando os elementos conforme necessário. A direção de fluxo padrão para um FlowPanel é da esquerda para a direita e de cima para baixo.

O exemplo de marcação a seguir demonstra como o FlowPanel quebra e encapsula o conteúdo. O FlowPanel contém quatro telas quadradas de uma polegada. O FlowPanel tenta exibir seus elementos filho da esquerda para a direita e de cima para baixo.

<Border xmlns="https://schemas.microsoft.com/2003/xaml" Background="White">
  <FlowPanel>
      <Border Background="Red" Width="1in" Height="1in"/>
      <Border Background="Green" Width="1in" Height="1in"/>
      <Border Background="Blue" Width="1in" Height="1in"/>
      <Border Background="Yellow" Width="1in" Height="1in"/>
  </FlowPanel>
</Border>

A Figura 3-3 mostra a saída quando o FlowPanel pode ajustar todos os elementos em uma única linha. A Figura 3-4 demonstra o FlowPanel encapsulando o último elemento em uma nova linha. A Figura 3-5 mostra o pior caso em que o FlowPanel deve colocar cada elemento em sua própria linha. A Figura 3-6 mostra o último elemento encapsulando para uma nova linha e a Figura 3-7 mostra cada elemento encapsulando para uma nova linha.

Figura 3-5. O FlowPanel quebra as linhas somente quando necessário.

Figura 3-6. O painel FlowPanel encapsulando o último elemento em uma nova linha

Figura 3-7. O painel FlowPanel encapsulando cada elemento em uma nova linha

TextPanel

O painel TextPanel formata, dimensiona e desenha texto. Essa classe de painel dá suporte a várias linhas de texto, bem como a vários formatos de texto. Normalmente, você usará a classe TextPanel quando precisar de suporte de layout complexo. No entanto, quando você precisa apenas de uma exibição de texto simples, é melhor usar o elemento Text .

O exemplo de marcação a seguir demonstra como o TextPanel quebra e encapsula o conteúdo. O TextPanel ajusta o número de colunas e a altura de cada coluna conforme você redimensiona a janela.

<Border xmlns="https://schemas.microsoft.com/2003/xaml" Background="White">
  <TextPanel 
    ColumnCount="3" 
    ColumnWidth="200px" 
    ColumnGap="25px"
    ColumnRuleWidth="5px"
    ColumnRuleBrush="blue">

    <Block Background="LightGray">
      <Inline FontFamily="Arial" FontWeight="Bold"
              FontSize="16pt">Transcript of the 
           <Italic>Nicolay Draft</Italic> 
           of the Gettysburg Address.
      </Inline>
    </Block>
    §
  </TextPanel>
</Border>

A Figura 3-8 mostra a saída resultante.

Figura 3-8. O TextPanel com várias características de fonte, colunas e formatação

GridPanel

O painel GridPanel exibe dados tabulares. O GridPanel dá suporte a muitas propriedades que você pode usar para personalizar o layout dos dados tabulares. Por exemplo, você pode definir as propriedades Colunas e Linhas para controlar o número de colunas e linhas na grade. Da mesma forma, as propriedades ColumnStyles e RowStyles permitem definir uma coleção de propriedades que o GridPanel aplica às linhas e colunas, respectivamente.

GridPanel organiza seus filhos em ordem, começando com a célula superior esquerda e movendo-se para a direita até o final da linha. Um filho poderá levar mais de uma coluna se você definir a propriedade GridPanel.ColumnSpan no filho. Da mesma forma, GridPanel.RowSpan permite que um filho abrange várias linhas.

A marcação a seguir exibe uma interface do usuário da Calculadora que é bastante semelhante ao utilitário calculadora do Windows.

<Border xmlns="https://schemas.microsoft.com/2003/xaml" Background="#DEE7F7">
<DockPanel Dock="Left">
  <Border  BorderThickness="0,0,0,0">
<!-- Padding="10, 10, 10, 10"  -->
  <GridPanel Columns="7">
    <GridPanel.ColumnStyles>
      <Column Width="16%"/>
      <Column Width="4%"/>
      <Column Width="16%"/>
      <Column Width="16%"/>
      <Column Width="16%"/>
      <Column Width="16%"/>
      <Column Width="16%"/>
    </GridPanel.ColumnStyles>

    <GridPanel.RowStyles>
      <Row Height="25"/>
      <Row Height="10"/>
      <Row Height="35"/>
      <Row Height="7"/>
      <Row Height="35"/>
      <Row Height="35"/>
      <Row Height="35"/>
      <Row Height="35"/>
    </GridPanel.RowStyles>

        <Border GridPanel.ColumnSpan="7" BorderBrush="#DEE7F7" 
                BorderThickness="2,2,2,2" Background="White">
            <Text HorizontalAlignment="right"
                  ID="CalcText">0.</Text>    
        </Border>

        <Text GridPanel.ColumnSpan="7"/>

        <Border BorderThickness="0,0,0,0">
          <GridPanel>
            <Border BorderBrush="#DEE7F7" BorderThickness="2,2,2,2">
               <Text Width="16%"
                  HorizontalAlignment="center"></Text>
            </Border>
          </GridPanel>
        </Border>

        <Text Width="4%"/>
        <DockPanel GridPanel.ColumnSpan="5" Dock="Left">
          <Button Width="33.33%" Foreground="Red">Backspace</Button>
          <Button Width="33.33%" Foreground="Red">CE</Button>
          <Button Width="33.33%" Foreground="Red">C</Button>
        </DockPanel>

        <Text GridPanel.ColumnSpan="7"/>

        <Button Foreground="Red">MC</Button>
        <Text/>
        <Button Foreground="Blue">7</Button>
        <Button Foreground="Blue">8</Button>
        <Button Foreground="Blue">9</Button>
        <Button Foreground="Red">/</Button>
        <Button Foreground="Blue">sqrt</Button>

        <Button Foreground="Red">MR</Button>
        <Text/>
        <Button Foreground="Blue">4</Button>
        <Button Foreground="Blue">5</Button>
        <Button Foreground="Blue">6</Button>
        <Button Foreground="Red">*</Button>
        <Button Foreground="Blue">%</Button>

        <Button Foreground="Red">MS</Button>
        <Text/>
        <Button Foreground="Blue">1</Button>
        <Button Foreground="Blue">2</Button>
        <Button Foreground="Blue">3</Button>
        <Button Foreground="Red">-</Button>
        <Button Foreground="Blue">1/x</Button>

        <Button Foreground="Red">M+</Button>
        <Text/>
        <Button Foreground="Blue">0</Button>
        <Button Foreground="Blue">+/-</Button>
        <Button Foreground="Blue">.</Button>
        <Button Foreground="Red">+</Button>
        <Button Foreground="Red">=</Button>

  </GridPanel>
</Border>
</DockPanel>
</Border>

A Figura 3-9 mostra a saída resultante.

Figura 3-9. O GridPanel como calculadora

Fixedpanel

O painel FixedPanel permite que você especifique os locais e tamanhos exatos de cada elemento. Elementos em um FixedPanel sempre serão exibidos no mesmo local e tamanho em todos os dispositivos. Discutirei o painel FixedPanel mais adiante neste capítulo na seção "Serviços de Layout de Documento".

Controles

O XAML tem todos os controles que você espera do Windows: botões, caixas de marcar, botões de opção, caixas de listagem, caixas de combinação, menus, barras de rolagem, controles deslizantes e assim por diante. Este exemplo demonstra alguns dos controles comuns fornecidos no Longhorn. Você pode ver os resultados na Figura 3-10.

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
<DockPanel>
  <Menu DockPanel.Dock="Top">
    <MenuItem Header="File">
      <MenuItem Header="New" />
      <MenuItem Header="Open" />
    </MenuItem>

    <MenuItem Header="Edit">
      <MenuItem Header="Cut"/>
      <MenuItem Header="Copy"/>
      <MenuItem Header="Paste"/>
    </MenuItem>
  </Menu>

<FlowPanel>

<Button> Button </Button>
<Border Width="15"/>

<CheckBox Checked="true"> CheckBox </CheckBox>
<Border Width="15"/>

<RadioButtonList>
  <RadioButton> RadioButton 1 </RadioButton>
  <RadioButton Checked="true"> RadioButton 2 </RadioButton>
  <RadioButton> RadioButton 3 </RadioButton>
</RadioButtonList>
<Border Width="15"/>

<ListBox>
   <ListItem> ListItem 1 </ListItem> 
   <ListItem> ListItem 2 </ListItem> 
   <ListItem> ListItem 3 </ListItem> 
</ListBox>
<Border Width="15"/>

<ComboBox>
   <ListItem> ListItem 1 </ListItem> 
   <ListItem> ListItem 2 </ListItem> 
   <ListItem> ListItem 3 </ListItem> 
</ComboBox>
<Border Width="15"/>

    <DockPanel>
      <VerticalSlider DockPanel.Dock="Top"  Height="200"
             Minimum="0" Maximum="255" Value="75"
             SmallChange="1" LargeChange="16"/> 
      <Text DockPanel.Dock="Bottom">Slider</Text>
    </DockPanel>
<Border Width="15"/>

    <DockPanel>
      <VerticalScrollBar DockPanel.Dock="Top" 
             Minimum="0" Maximum="255" Value="125" Height="200"
             SmallChange="1" LargeChange="16"/> 
      <Text DockPanel.Dock="bottom">ScrollBar</Text>
    </DockPanel>
<Border Width="15"/>
   
<TextBox> TextBox </TextBox> 

</FlowPanel>
</DockPanel>
</Border>

Figura 3-10. Um exemplo de controles XAML

O XAML também permite combinar elementos e controles para criar efeitos avançados. Chamamos isso de combinação de elementos de composição de controle e é um dos aspectos mais poderosos de Longhorn. Por exemplo, para criar um botão com uma imagem, você coloca um elemento Image dentro de Button:

<Button> 
  <Image Source="tulip.jpg"/>
</Button>

Para ter uma imagem e um texto no Botão, como você pode ver na Figura 3-11, usamos nosso velho amigo DockPanel:

<Button> 
  <DockPanel>
     <Image Source="tulip.jpg"/>
     <Text DockPanel.Dock="fill" VerticalAlignment="center"> Button 
         <Italic>with Image!</Italic>
     </Text>
  </DockPanel>
</Button>

Figura 3-11. Um botão com uma imagem e um texto

Você pode colocar praticamente qualquer coisa dentro de qualquer coisa, incluindo este exemplo estranho de uma Caixa de Seleção dentro de um Botão:

<Button> 
  <CheckBox Checked="true"> CheckBox </CheckBox>
</Button>

A composição é poderosa o suficiente para que muitos dos controles Longhorn sejam realmente definidos usando composição. Por exemplo, um ScrollBar é, na verdade, dois botões e um controle deslizante, além de alguma lógica do manipulador de eventos para conectá-los.

O XAML também inclui alguns "primitivos" de controle, que são usados principalmente com composição de controle para criar efeitos maiores. Por exemplo, ScrollViewer usa um filho (normalmente um painel) e adiciona barras de rolagem a ele. Este exemplo coloca uma lista muito grande de elementos CheckBox dentro de um ScrollViewer, algo que antes de Longhorn exigia um controle separado, como CheckedListBox do Windows Forms:

<Border BorderThickness="1" BorderBrush="black">
  <ScrollViewer Height="100" Width="200">
    <GridPanel Columns="1">
      <CheckBox Checked="true"> CheckBox 1</CheckBox>
      <CheckBox Checked="true"> CheckBox 2</CheckBox>
      <CheckBox Checked="true"> CheckBox 3</CheckBox>
      <CheckBox Checked="true"> CheckBox </CheckBox>
      <CheckBox Checked="true"> CheckBox </CheckBox>
      <CheckBox Checked="true"> CheckBox </CheckBox>
      <CheckBox Checked="true"> CheckBox </CheckBox>
      <CheckBox Checked="true"> CheckBox </CheckBox>
    </GridPanel>
  </ScrollViewer>
</Border>

Recursos e estilos

O XAML fornece recursos muito avançados para personalizar a aparência do aplicativo, por meio de entidades conhecidas como estilos. No entanto, antes de entrarmos neste tópico, precisamos aprender sobre os recursos. O termo recursos usados neste contexto simplesmente se refere a uma maneira de reutilizando objetos e valores comumente definidos. Vejamos um exemplo:

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <FlowPanel>
    <FlowPanel.Resources>
      <SolidColorBrush def:Name="MyColor" Color="Gold"/>
    </FlowPanel.Resources>
    <Button Background="{MyColor}"/>
    <Ellipse Fill="{MyColor}"/>
  </FlowPanel>
</Border>

Esse código define um novo recurso chamado MyColor, cujo tipo é SolidColorBrush e o valor é Gold. Esse recurso faz parte da coleção Recursos do FlowPanel. Cada elemento tem uma coleção Resources . Você pode definir recursos em qualquer elemento desejado, mas na maioria das vezes você os colocará apenas no elemento raiz. Nesse caso, o FlowPanel.

Depois de definir um recurso, você poderá referenciar o recurso em um valor de propriedade colocando o nome do recurso em chaves, como você vê aqui:

<Button Background="{MyColor}"/>

Quando o processador XAML vir {MyColor} neste exemplo, ele primeiro marcar a coleção Resources do botão. Como Button não tem uma definição de MyColor (sua coleção Resources está vazia), ele marcar pai do Botão— o FlowPanel.

Um tipo particularmente útil de recurso é um Estilo. Style é o nome da classe e o nome de uma propriedade que todos os elementos têm. Um Estilo define as propriedades a serem definidas em um elemento , que usa esse estilo designado. Este exemplo define um Estilo chamado MyStyle e aplica esse estilo a um botão:

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <FlowPanel>
    <FlowPanel.Resources>

      <Style def:Name="MyStyle">               
           <Button Background="Red" FontSize="24"/>
      </Style>   

    </FlowPanel.Resources>
    <Button>Normal</Button>

    <Button Style="{MyStyle}">Styled</Button>

  </FlowPanel>
</Border>

Você também pode definir um recurso Style sem nome, que se torna o estilo padrão do elemento para elementos em que você não especifica uma propriedade Style explícita. Este exemplo adiciona um estilo padrão ao exemplo anterior:

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <FlowPanel>
    <FlowPanel.Resources>

      <Style>               
           <Button Background="Green" FontSize="15"/>
      </Style>   

      <Style def:Name="MyStyle">               
           <Button Background="Red" FontSize="24"/>
      </Style>   
    </FlowPanel.Resources>
    <Button>Normal</Button>
    <Button Style="{MyStyle}">Styled</Button>
  </FlowPanel>
</Border>

Você pode fazer um tipo de herança de estilo definindo a propriedade BasedOn da classe Style . Referenciar a nova classe Style definirá todas as propriedades que o Estilo antigo fez, além das propriedades adicionais especificadas. O exemplo a seguir define dois estilos: o primeiro define a propriedade Background e o segundo, com base no primeiro, define a propriedade FontSize .

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <FlowPanel>
    <FlowPanel.Resources>
      <Style def:Name="Style1">
           <Button Background="Red"/>
      </Style>   

      <Style def:Name="Style2" BasedOn="{Style1}">
           <Button FontSize="24"/>
      </Style>   
    </FlowPanel.Resources>
    <Button Style="{Style1}">Style 1</Button>
    <Button Style="{Style2}">Style 2</Button>
  </FlowPanel>
</Border>

É até possível que um Estilo defina propriedades condicionalmente, usando um recurso conhecido como gatilhos de propriedade. Style tem uma propriedade chamada VisualTriggers, que é uma coleção de PropertyTriggers. Cada PropertyTrigger especifica uma condição usando as propriedades Property e Value e contém uma coleção de instruções Set . Quando a propriedade do elemento estilizado corresponde a esse valor, as instruções Set são aplicadas e quando a condição não é mais verdadeira, os valores são desaplicados, como se nunca tivessem sido definidos em primeiro lugar. Este exemplo usa gatilhos de propriedade para deixar o botão verde quando o mouse estiver sobre o botão e vermelho, caso contrário:

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
           xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <FlowPanel>
    <FlowPanel.Resources>
      <Style def:Name="Style1">
           <Button Background="Red"/>

           <Style.VisualTriggers>
             <PropertyTrigger Property="IsMouseOver" Value="true">
               <Set PropertyPath="Background" Value="Green"/>
             </PropertyTrigger>
            </Style.VisualTriggers>
      </Style>   
    </FlowPanel.Resources>
    <Button Style="{Style1}">Style 1</Button>
  </FlowPanel>
</Border>

Muitos controles XAML usam composição de controle. Eles combinam vários controles menores para criar um controle maior e mais complicado. Estilos até permitem que você altere isso! Ao especificar uma composição diferente, você pode redefinir completamente a aparência de um controle enquanto ainda mantém seu comportamento.

Depois de declarar o elemento de estilo e suas propriedades, a <marca Style.VisualTree> especifica dentro do Style quais elementos compor para criar o controle maior. Você pode definir as propriedades dos elementos filho como de costume e dar a esses filhos seus próprios filhos. Você também pode usar o aliasing de propriedade para definir valores de propriedade. Por exemplo, Name1="*Alias(Target=Name2)" definirá a propriedade Name1 do filho como a propriedade Name2 do controle maior. O exemplo a seguir cria um estilo para Button que altera a composição para obter uma aparência redonda, como você pode ver na Figura 3-12. As propriedades Plano de Fundo e Conteúdo do botão são alias em pontos apropriados na árvore visual.

<Border Background="white"
    xmlns="https://schemas.microsoft.com/2003/xaml"
    xmlns:def="Definition">
  <FlowPanel>
    <FlowPanel.Resources>
      <Style def:Name="RoundButton">
    
         <Button FontSize="20"/>
     
         <Style.VisualTree>
             <Canvas>
                 <Rectangle ID="MainRect" 
                     RadiusX="10" RadiusY="10" 
                     Fill="*Alias(Target=Background)" 
                     Width="100%" Height="100%" />

                 <FlowPanel Width="100%" Height="100%" >
                     <ContentPresenter  
                          ContentControl.Content="*Alias(Target = Content)" 
                          Margin="15,3,15,5"/>
                 </FlowPanel>
             </Canvas>
         </Style.VisualTree>
      </Style>
    </FlowPanel.Resources>
 
    <Button Style="{RoundButton}">
        standard RoundButton
    </Button>

    <Button Background="red" Style="{RoundButton}">
        red RoundButton
    </Button>

    <Button>
        standard button
    </Button>

    <Button Background="red">
        red standard button
    </Button>
  </FlowPanel>
</Border>

Figura 3-12. Alguns botões RoundButton e standard em um FlowPanel

Elementos gráficos e animações

O XAML fornece amplo suporte para desenhar formas, transformar o estado de um objeto e animar quase qualquer propriedade de um objeto. Você usa elementos Shape para desenhar, transformar elementos para alterar uma propriedade ou um objeto e elementos Animation para alterar uma propriedade de um objeto ao longo do tempo.

Formas

O XAML fornece um conjunto de elementos Shape para desenho, que incluem elipse, linha, retângulo, caminho, polígono e polilinha. Uma Forma tem um Preenchimento, que é a cor da tela de fundo, e um Traço, que é a cor da estrutura de tópicos. Preenchimento e Traço padrão para transparente, portanto, certifique-se de definir pelo menos um deles! A propriedade StrokeWidth controla a espessura da estrutura de tópicos.

As formas não podem ter elementos filho. Normalmente, você coloca formas dentro de uma Tela, portanto, a primeira forma na marcação será a primeira desenhada. Este exemplo ilustra algumas das formas básicas, que você também pode ver na Figura 3-13:

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <Canvas Height="400" Width="400">
        <Ellipse CenterX="70" CenterY="75" 
         RadiusX="30" RadiusY="50" 
         Fill="yellow" Stroke="red" StrokeThickness="15"/>

        <Rectangle RectangleLeft="150" RectangleTop="20" 
         RectangleHeight="100" RectangleWidth="40"
         Fill="lightBlue" Stroke="green"/>

        <Line X1="20" Y1="220" X2="150" Y2="240"
         Stroke="black" StrokeThickness="5"/>

        <Polygon Points="220,140 270,240 170,240"
         StrokeLineJoin="Round"
         Stroke="black" StrokeThickness="20"/>
  </Canvas>
</Border>

Figura 3-13. Várias formas em uma tela

Até agora, usamos apenas cores sólidas com as propriedades Stroke e Fill . Mas em XAML, em praticamente qualquer lugar você pode usar uma cor que pode especificar um Brush. SolidColorBrush é o tipo de pincel que usamos até agora, mas o XAML também dá suporte a ImageBrush, LinearGradientBrush e RadialGradientBrush. ImageBrush tem uma propriedade ImageSource que especifica o nome do arquivo de imagem. SolidColorBrush tem uma propriedade Color . LinearGradientBrush e RadialGradientBrush contêm um GradientStopCollection, que permite gradientes muito complicados. Este exemplo define quatro pincéis como recursos e os usa como Traço ePreenchimento das reticências. Você pode ver como eles se parecem na Figura 3-14.

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <Border.Resources>
        <LinearGradientBrush def:Name="lineargradient" StartPoint="0,0" 
                             EndPoint="1,1"  >
          <LinearGradientBrush.GradientStops>
            <GradientStopCollection>
              <GradientStop Color="Blue" Offset="0"/>
              <GradientStop Color="white" Offset="1"/>
            </GradientStopCollection>
          </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>

        <RadialGradientBrush def:Name="radialgradient" Focus="0.3,0.3">
          <RadialGradientBrush.GradientStops>
            <GradientStopCollection>
              <GradientStop Color="red" Offset="0"/>
              <GradientStop Color="yellow" Offset="1"/>
            </GradientStopCollection>
          </RadialGradientBrush.GradientStops>
        </RadialGradientBrush>

        <ImageBrush def:Name="image" ImageSource="Tulip.jpg" TileMode="Tile"/>

        <SolidColorBrush def:Name="solid" Color="gray"/>
  </Border.Resources>

  <Canvas Height="400" Width="400">
        <Ellipse CenterX="100" CenterY="75" 
         RadiusX="90" RadiusY="50" 
         Fill="{lineargradient}" Stroke="{image}" StrokeThickness="15"/>

        <Ellipse CenterX="300" CenterY="170" 
         RadiusX="50" RadiusY="150" 
         Fill="{radialgradient}" Stroke="{solid}" StrokeThickness="15"/>
  </Canvas>
</Border>

Figura 3-14. Gradientes no trabalho

Transformações

O XAML dá suporte a vários tipos de Transformações. RotateTransform gira pela quantidade da propriedade Angle . TranslateTransform move as coisas de acordo com as propriedades X e Y . ScaleTransform reduzirá ou ampliará de acordo com as propriedades ScaleX e ScaleY . SkewTransform inclina as coisas, usando as propriedades AngleX, AngleY e Center . MatrixTransform dá suporte a transformações arbitrárias de affine. Por fim, TransformCollection é uma Transformação que permite combinar várias transformações.

Algumas classes, como Brush, têm uma propriedade Transform . Para outros casos, você pode usar o elemento TransformDecorator , que tem uma propriedade Transform . TransformDecorator transformará seu elemento filho. (Como Border, ele pode ter apenas um filho.) TransformDecorator pode conter qualquer tipo de filho, incluindo formas, painéis e controles. Este exemplo usa para TransformDecorators. O primeiro contém uma Elipse e gira 45 graus. O segundo TransformDecorator contém uma ListBox e gira e dimensiona a ListBox. Você pode ver como são as formas na Figura 3-15.

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <Canvas Height="400" Width="400">
     <TransformDecorator Transform="rotate 45">
       <Ellipse CenterX="100" CenterY="75" 
         RadiusX="90" RadiusY="50" 
         Fill="white" Stroke="black" StrokeThickness="15"/>
     </TransformDecorator>

     <TransformDecorator Canvas.Top="200" Canvas.Left="100">
       <TransformDecorator.Transform>
         <TransformCollection>
           <RotateTransform Angle="135"/>
           <ScaleTransform ScaleX="2" ScaleY="4"/>
         </TransformCollection>
        </TransformDecorator.Transform>

        <ListBox >
          <ListItem> ListItem 1 </ListItem> 
          <ListItem> ListItem 2 </ListItem> 
          <ListItem> ListItem 3 </ListItem> 
        </ListBox>
     </TransformDecorator>
  </Canvas>
</Border>

Figura 3-15. Uma ListBox e elipse distorcidas

Animações

O XAML também dá suporte a animações. Você pode animar quase todas as propriedades. Algumas propriedades têm uma propriedade "Animations" correspondente, por exemplo, RotateTransform.Angle e RotateTransform.AngleAnimations. Em outros casos, você pode atribuir uma coleção de animação a uma propriedade usando a sintaxe de propriedade composta. Por exemplo, consulte o seguinte código:

  <Button>
       <Button.Width>
         … put animation collection here …
       </Button.Width>
  </Button>

Cada tipo de propriedade tem uma coleção de animações separada. O tipo de Button.Width é Length, portanto, um usa LengthAnimationCollection. Da mesma forma, os próprios objetos de animação são específicos para o tipo da propriedade que você anima — LengthAnimationCollection contém um conjunto de objetos LengthAnimation .

Os objetos de animação têm uma propriedade From e To , cujos tipos correspondem ao tipo da propriedade que está sendo animada. O objeto de animação também tem as propriedades Begin, Duration e End , que são medidas em segundos e controlam o tempo da animação. Begin também dá suporte ao valor Immediate e Duration dá suporte a Indefinido. Você pode usar as propriedades RepeatCount e RepeatDuration para repetir a animação automaticamente. A propriedade Fill especifica o que acontece com a propriedade depois que a animação termina. Fill="Hold" é um dos valores mais importantes; ele mantém a propriedade no valor final da animação.

As classes de animação não fazem parte do namespace XAML padrão, portanto, você precisará usar o <? Constructos de mapeamento> e xmlns para carregar o namespace MSAvalon.Windows.Media.Animation . Como esse namespace contém classes de várias DLLs, você precisará de um separado<? Mapeamento> e xmlns para cada DLL.

O próximo exemplo anima duas propriedades, a propriedade RotateTransform.Angle e a propriedade Button.Width , que usam classes de ambos os namespaces de animação. A Figura 3-16 mostra o botão em momentos diferentes.

<?Mapping XmlNamespace="animC" ClrNamespace="MSAvalon.Windows.Media.Animation" 
                               Assembly="PresentationCore" ?>
<?Mapping XmlNamespace="animF" ClrNamespace="MSAvalon.Windows.Media.Animation" 
                               Assembly="PresentationFramework" ?>
<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:animC="animC"
       xmlns:animF="animF"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <Canvas Height="400" Width="400">
     <TransformDecorator Canvas.Top="200" Canvas.Left="100">
       <TransformDecorator.Transform>
         <TransformCollection>
           <RotateTransform Angle="135">
              <RotateTransform.AngleAnimations>
                 <animC:DoubleAnimationCollection>
                    <animC:DoubleAnimation From="0" To="360" Duration="4" 
                       AutoReverse="True" 
                       RepeatDuration="Indefinite"/>
                 </animC:DoubleAnimationCollection>

              </RotateTransform.AngleAnimations>

           </RotateTransform>
         </TransformCollection>
        </TransformDecorator.Transform>

        <ListBox >
          <ListItem> ListItem 1 </ListItem> 
          <ListItem> ListItem 2 </ListItem> 
          <ListItem> ListItem 3 </ListItem> 
        </ListBox>
     </TransformDecorator>

     <Button Width="40" Canvas.Top="10" Canvas.Left="10">
       <Button.Width>
         <animF:LengthAnimationCollection>
           <animF:LengthAnimation From="40" To="300" 
             AutoReverse="true" Begin="1" Duration="1.2"
             RepeatDuration="Indefinite"/>
         </animF:LengthAnimationCollection>
       </Button.Width>
       Button
     </Button>

  </Canvas>
</Border>

Figura 3-16. Exibições do botão animado em momentos diferentes

Serviços de Documentos

A plataforma Longhorn fornece serviços extensivos que dão suporte a uma melhor experiência de exibição de documentos online. Há dois serviços main: um controle projetado para exibir, paginar e navegar pelo conteúdo de um documento e serviços de layout projetados para aprimorar a experiência de leitura.

Controle PageViewer

Use o controle PageViewer quando quiser exibir um documento para o usuário para exibição online. O controle PageViewer fornece paginação e funcionalidade de navegação de página. O controle formata automaticamente o conteúdo do documento em páginas separadas. O usuário pode navegar diretamente para páginas diferentes usando os controles fornecidos pelo visualizador de páginas.

Paginação e navegação

Tradicionalmente, o conteúdo online, como páginas da Web, era contínuo. Uma interface do usuário forneceu barras de rolagem para permitir que você exiba conteúdo que não poderia caber na área visível. Na verdade, você "rolaria" a janela de exibição para a posição no documento que você queria ver.

Com a paginação, você divide o conteúdo do documento em uma ou mais páginas individuais, semelhante a um livro. A plataforma Longhorn dá suporte ao conteúdo paginado, incluindo vários controles que ajudam você a exibir e navegar pelo conteúdo exibido como páginas discretas. Além disso, o Longhorn fornece uma API (interface de programação de aplicativo) de paginação para estender esses recursos e fornecer suporte avançado de paginação para aplicativos de paginação personalizados.

O controle PageViewer é, na verdade, um controle complexo criado a partir de controles menores usando técnicas de composição de controle que descrevi anteriormente. O controle PageViewer usa os controles PageSource e PageElement para fornecer sua funcionalidade de paginação. O controle PageSource quebra e formata o conteúdo entre páginas. O controle PageElement renderiza uma única página. O controle PageViewer também usa o controle PageBar para permitir que você navegue pelas páginas.

Usar o controle PageViewer é muito simples. Para exibir um documento conhecido, você pode usá-lo conforme mostrado no código a seguir. É claro que você pode conectar manipuladores de eventos e alterar o documento de origem para fazer com que o visualizador de página exiba documentos diferentes.

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <PageViewer Source="AuthorsandPublishers.xaml" />
</Border>

A Figura 3-17 mostra o visualizador de páginas hospedado em uma janela do navegador exibindo seu documento. Observe os controles de navegação de página na parte superior do documento.

Figura 3-17. O controle PageViewer

Serviços de Layout de Documento

O Longhorn também fornece serviços de layout de documento projetados para melhorar a experiência de leitura. Longhorn contém suporte para dois novos tipos de documentos:

  • Documentos de fluxo adaptável
  • Documentos de layout fixos

Esses novos formatos de documento permitem que os desenvolvedores forneçam aos usuários de seus aplicativos uma melhor experiência de leitura de documentos.

Os documentos de fluxo adaptável usam elementos de marcação especializados que declaram que um documento deve ser adaptável. O Longhorn otimiza automaticamente um documento adaptável para usar melhor o espaço de tela disponível e fornecer a melhor experiência de leitura para o usuário com base nos recursos ou limitações de seu sistema.

Por exemplo, o usuário pode ter uma das telas de tela larga de taxa de proporção 16 por 9 introduzidas recentemente. É muito difícil ler uma linha de texto que abrange uma linha horizontal longa. Dependendo da largura da janela, um documento adaptável pode dividir o texto em duas, três ou mais colunas, reduzindo assim o esforço de um usuário para digitalizar uma linha de texto.

Em outro exemplo, um documento pode conter uma imagem e um texto que fluem ao redor da imagem. À medida que você reduz o tamanho da janela do documento em um documento não ativo, a imagem permanece um tamanho fixo e você vê cada vez menos o texto. Um documento adaptável pode reduzir a imagem quando determina que o texto insuficiente está visível na janela. Isso permite que o leitor ainda tenha uma ideia geral do que a imagem retrata, mas continue a ler o texto no contexto da imagem. Em uma janela menor, ver cada pixel de uma imagem provavelmente será menos importante e útil para o leitor do que ser capaz de ler mais texto. Uma alternativa, como separar a imagem e o texto ao redor em páginas separadas, derrota a intenção do autor do documento, que era apresentar o texto e a imagem juntos no contexto.

Os documentos de layout fixo aparecem da mesma forma todas as vezes, independentemente do tamanho da tela, do tamanho da janela ou do dispositivo de saída do visualizador. Você cria um documento de layout fixo usando elementos de marcação especializados ou imprimindo um documento usando um driver de impressora WVG (Microsoft Windows Vector Graphics).

Documentos de Layout Adaptável

Em um documento de layout adaptável, você fornece as principais preferências na marcação de nível raiz. Longhorn então pode renderizar o documento de uma maneira que faça o melhor uso da área da janela e aprimore sua legibilidade. Longhorn determina automaticamente a largura ideal e o número de colunas para uma página, tamanhos ideais para todos os elementos de texto, tamanhos e posições ideais para todas as figuras e as larguras de margens e sarjetas para dar a melhor apresentação geral do conteúdo.

Produzindo um documento de layout adaptável

Para criar um documento de layout adaptável, use marcação declarativa semelhante à seguinte:

<Border
       xmlns="https://schemas.microsoft.com/2003/xaml"
       xmlns:def="Definition"
       Background="BlanchedAlmond" 
   >
  <AdaptiveMetricsContext ColumnPreference="Medium"
                          FontFamily="Arial">
    <TextPanel Background="white"> 
      <Section>
        <Heading OutlineLevel="1">Adaptive Layout Example</Heading>
        <Paragraph>
This example shows the advanced capabilities of Adaptive Flow 
Layout. Lorem ipsum dolor sit amet, consectetuer adipiscing 
elit, sed diam nonummy nibh euismod tin cidunt ut laoreet dolore 
magna aliquam erat volutpat. Ut wisi enim ad minim veni am, quis 
nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip 
ex ea commodo consequat. Duis autem vel eum iriure.</Paragraph>
        <Paragraph>
        <Image TextPanel.FlowBehavior="Figure" Source="picture1.jpg"
               TextPanel.Emphasis="Medium" />
Notice how images and text are flowed intelligently to enhance the 
reading experi ence. Lorem ipsum dolor sit amet, consectetuer 
adipiscing elit, sed diam nonummy  nibh euismod tincidunt ut laoreet 
dolore magna aliquam erat volutpat. Ut wisi e nim ad minim veniam, 
quis nostrud  exerci tation ullamcorper suscipit lobortis ni sl ut 
aliquip ex ea commodo consequat. Duis autem vel eum iriure.
</Paragraph>
        <Paragraph>Adaptive layout is an exciting new feature of Longhorn.
        <Image TextPanel.FlowBehavior="Figure" Source="picture2.jpg"
               TextPanel.Emphasis="Low" />
Lorem ipsum dolor sit amet, consectetuer 
adipiscing elit, sed diam nonummy  nibh euismod tincidunt ut laoreet 
dolore magna aliquam erat volutpat. Ut wisi e nim ad minim veniam, 
quis nostrud  exerci tation ullamcorper suscipit lobortis ni sl ut 
aliquip ex ea commodo consequat. Duis autem vel eum iriure.
</Paragraph>
      </Section>
    </TextPanel>
  </AdaptiveMetricsContext>
</Border>

documentos do Fixed-Layout

Você usa um documento de layout fixo para apresentar o conteúdo do documento exatamente no mesmo layout e formato, independentemente do software de aplicativo, hardware e sistema operacional usado. Além disso, um documento de layout fixo é renderizado de forma idêntica em todos os dispositivos de saída. Um documento de layout fixo é um conjunto de objetos que descrevem coletivamente a aparência de uma ou mais páginas.

Produzindo um documento Fixed-Layout

Você pode usar duas técnicas diferentes para produzir um documento de layout fixo:

  • Imprimir um documento sem marcação em um arquivo usando o driver de impressora Longhorn
  • Escrever um documento de layout fixo usando XAML

Quando você imprime um documento usando a maioria dos aplicativos Do Microsoft Win32 (por exemplo, o Microsoft Office) usando o driver de impressora Longhorn, o driver de impressora criará um arquivo XAML que contém marcação para paginar e posicionar cada caractere, imagem ou gráfico vetor no documento impresso.

Você pode optar por gerar o documento como um arquivo de marcação diretamente ou incluir o arquivo de marcação dentro de um contêiner. Ao selecionar a saída do contêiner, você também pode aplicar direitos digitais e proteção de documentos ao documento.

Como alternativa, você pode criar XAML usando um editor. Veja a seguir um exemplo esquelético de documento de layout fixo:

<FixedPanel xmlns="https://schemas.microsoft.com/2003/xaml/" >
  <FixedPage Width="8.50in" Height="11.00in"> <!-- PAGE 1 -->
    <Text FontFamily="Arial" FontSize="8.4" FixedPage.Left="1.250in"
          FixedPage.Top="0.530in" FontWeight="Bold">1.</Text>
    <Text FontFamily="Arial" FixedPage.Left="1.350in" FixedPage.Top="0.500in"
          FontWeight="Bold" FontSize="12">Fixed Document</Text>
  </FixedPage>
  <FixedPage>
    <Text>This is page 2</Text>
  </FixedPage>
  <FixedPage>
    <Text>This is page 3</Text>
  </FixedPage>
</FixedPanel>

Resumo

Os painéis permitem dividir a superfície de exibição em áreas com características de layout diferentes. Você tem uma grande variedade de controles que pode usar para preencher os painéis de uma tela. Formas, Transformações e Animações permitem produzir saída gráfica dinâmica. Usando a composição de controle, você pode combinar esses recursos para produzir praticamente qualquer interface do usuário desejada. Você pode produzir documentos adaptáveis que dispõem seu conteúdo de forma inteligente e facilitam a leitura do leitor. Como alternativa, você pode posicionar precisamente cada elemento em uma página e controlar a paginação explicitamente para produzir um documento que aparece exatamente como você deseja, independentemente do dispositivo de saída. Além disso, você pode fazer tudo declarativamente usando XAML. Isso com certeza é melhor que escrever um manipulador de mensagens WM_PAINT!

Prossiga para o Capítulo 4: Armazenamento