XAML - Guia rápido

XAML significa Extensible Application Markup Language. É uma linguagem simples e declarativa baseada em XML.

  • Em XAML, é muito fácil criar, inicializar e definir propriedades de um objeto com relações hierárquicas.

  • É usado principalmente para projetar GUIs.

  • Ele também pode ser usado para outros fins, por exemplo, para declarar o fluxo de trabalho no Workflow Foundation.

O XAML pode ser usado em diferentes plataformas, como WPF (Windows Presentation Foundation), Silverlight, Mobile Development e Windows Store App. Ele pode ser usado em diferentes versões do .Net framework e CLR (common language runtime).

Como funciona o XAML

XAML é um declarative linguagem no sentido em que define o WHAT e HOWvocê quer fazer. O processador XAML é responsável peloHOWparte para descobrir. Vamos dar uma olhada no seguinte esquema. Ele resume o lado XAML das coisas -

A figura ilustra as seguintes ações -

  • O arquivo XAML é interpretado por um processador XAML específico da plataforma.

  • O processador XAML transforma o XAML em código interno que descreve o elemento de interface do usuário.

  • O código interno e o código C # são vinculados por meio de definições de classes parciais e, em seguida, o compilador .NET cria o aplicativo.

Vantagens do XAML

Um dos problemas de longa data que todos nós enfrentamos com o design da GUI pode ser resolvido usando o XAML. Ele pode ser usado para projetar elementos de interface do usuário em aplicativos Windows Forms.

Nas estruturas GUI anteriores, não havia separação real entre a aparência de um aplicativo e como ele se comportava. Tanto a GUI quanto seu comportamento foram criados na mesma linguagem, por exemplo, C # ou VB.net, o que exigiria mais esforço do desenvolvedor para implementar a UI e o comportamento associado a ela.

Com o XAML, é muito fácil separar o comportamento do código do designer. Portanto, o programador XAML e o designer podem trabalhar em paralelo. Os códigos XAML são muito fáceis de ler e entender.

A Microsoft fornece duas ferramentas importantes para XAML -

  • Estúdio visual
  • Expression Blend

Atualmente, ambas as ferramentas podem criar XAML, mas o fato é que o Visual Studio é mais usado por desenvolvedores, enquanto o Expression Blend ainda é usado com mais frequência por designers.

A Microsoft fornece uma versão gratuita do Visual Studio, que pode ser baixada em https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx

Note- Para este tutorial, usaremos principalmente projetos WPF e o aplicativo da Windows Store. Mas a versão gratuita do Visual Studio não oferece suporte ao aplicativo da Windows Store. Portanto, para esse propósito, você precisará de uma versão licenciada do Visual Studio.

Instalação

Siga as etapas abaixo para instalar o Visual Studio em seu sistema -

  • Depois de baixar os arquivos, execute o instalador. A seguinte caixa de diálogo será exibida.

  • Clique no botão Instalar e iniciará o processo de instalação.

  • Assim que o processo de instalação for concluído com êxito, você verá a tela a seguir.

  • Feche esta caixa de diálogo e reinicie o computador, se necessário.

  • Agora abra o Visual Studio a partir do Menu Iniciar, que mostrará a seguinte caixa de diálogo. Levará algum tempo pela primeira vez, apenas para preparação.

Assim que tudo estiver pronto, você verá a janela principal do Visual Studio.

Primeiro passo para a implementação

Vamos começar com uma implementação simples. Siga as etapas abaixo -

  • Clique na opção de menu Arquivo → Novo → Projeto.

  • A seguinte caixa de diálogo será exibida -

  • Em Modelos, selecione Visual C # e selecione Aplicativo WPF. Dê um nome ao projeto e clique no botão OK.

  • No arquivo mainwindow.xaml, as seguintes marcas XAML são gravadas por padrão. Você entenderá todas essas tags posteriormente neste tutorial.

<Window x:Class = "FirstStepDemo.MainWindow"
   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" 
   xmlns:local = "clr-namespace:FirstStepDemo" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
         
   </Grid> 
</Window>

Por padrão, uma grade é definida como o primeiro elemento após a página.

Vamos adicionar um botão e um bloco de texto sob o elemento Grid. Isso é chamadoobject element syntax, um colchete angular esquerdo seguido do nome do que queremos instanciar, por exemplo, um botão, e definir uma propriedade de conteúdo. A string atribuída ao Conteúdo será exibida no botão. Agora defina a altura e a largura do botão como 30 e 50, respectivamente. De forma semelhante, inicialize as propriedades do bloco de texto.

Agora olhe para a janela de design. Você verá um botão. Agora pressione F5 para executar este código XAML.

<Window x:Class = "FirstStepDemo.MainWindow" 
   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" 
   xmlns:local = "clr-namespace:FirstStepDemo" 
   mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button Content = "First Button" Height = "30" Width = "80"/> 
      <TextBlock Text = "Congratulations you have successfully build your first app" 
         Height = "30" Margin = "162,180,122,109"/> 
   </Grid> 
	
</Window>

Ao compilar e executar o código acima, você verá a janela a seguir.

Parabéns! Você projetou seu primeiro botão.

Os aplicativos XAML também podem ser desenvolvidos no Mac. No Mac, o XAML pode ser usado como aplicativos iOS e Android. Para configurar o ambiente no Mac, vá para www.xamarin.com . Clique em Produtos e selecione a Plataforma Xamarin. Baixe o Xamarin Studio e instale-o. Ele permitirá que você desenvolva aplicativos para as várias plataformas.

XAML - Sintaxe C #

Neste capítulo, você aprenderá a sintaxe / regras básicas de XAML para escrever aplicativos XAML. Vamos dar uma olhada em um arquivo XAML simples.

<Window x:Class = "Resources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
         
   </Grid> 
</Window>

Como você pode ver no arquivo XAML acima, existem diferentes tipos de tags e elementos. A tabela a seguir descreve resumidamente todos os elementos.

Sr. Não Elementos e descrição
1

<Window

É o elemento de objeto de abertura ou contêiner da raiz.

2

x:Class="Resources.MainWindow"

É a declaração de classe parcial que conecta a marcação ao código de classe parcial definido nela.

3

xmlns

Mapeia o namespace XAML padrão para cliente / estrutura WPF

4

xmlns:x

Namespace XAML para linguagem XAML que mapeia para x: prefixo

5

>

Fim do elemento de objeto da raiz.

6

<Grid>

</Grid>

Iniciando e fechando tags de um objeto de grade vazio.

7

</Window>

Fechando o elemento do objeto

Regras de sintaxe para elemento de objeto

As regras de sintaxe para XAML são quase semelhantes a XML. Se você der uma olhada em um documento XAML, verá que, na verdade, é um arquivo XML válido. No entanto, um arquivo XML não pode ser um arquivo XAML válido. É porque em XML, o valor dos atributos deve ser uma string, enquanto em XAML, pode ser um objeto diferente que é conhecido como sintaxe de elemento de propriedade.

  • A sintaxe de um elemento Object começa com um colchete angular esquerdo (<) seguido pelo nome do objeto, por exemplo, Botão.

  • Defina algumas propriedades e atributos desse elemento de objeto.

  • O elemento Object deve ser fechado por uma barra (/) seguida imediatamente por um colchete angular direito (>).

Exemplo de objeto simples sem elemento filho -

<Button/>

Exemplo de elemento de objeto com alguns atributos -

<Button Content = "Click Me" Height = "30" Width = "60"/>

Exemplo de uma sintaxe alternativa para definir propriedades (sintaxe do elemento Property) -

<Button> 
   <Button.Content>Click Me</Button.Content> 
   <Button.Height>30</Button.Height> 
   <Button.Width>60</Button.Width> 
</Button>

Exemplo de objeto com elemento filho - StackPanel contém Textblock como elemento filho

<StackPanel Orientation = "Horizontal"> 
   <TextBlock Text = "Hello"/> 
</StackPanel>

Você pode usar o XAML para criar, inicializar e definir as propriedades dos objetos. As mesmas atividades também podem ser realizadas usando código de programação.

XAML é apenas outra maneira simples e fácil de projetar elementos de interface do usuário. Com o XAML, cabe a você decidir se deseja declarar objetos em XAML ou declará-los usando código.

Vamos dar um exemplo simples para demonstrar como escrever em XAML -

<Window x:Class = "XAMLVsCode.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "525"> 
	
   <StackPanel> 
      <TextBlock Text = "Welcome to XAML Tutorial" Height = "20" Width = "200" Margin = "5"/>
      <Button Content = "Ok" Height = "20" Width = "60" Margin = "5"/> 
   </StackPanel> 
	
</Window>

Neste exemplo, criamos um painel de pilha com um Botão e um Bloco de texto e definimos algumas das propriedades do botão e do bloco de texto, como Altura, Largura e Margem. Quando o código acima for compilado e executado, ele produzirá a seguinte saída -

Agora observe o mesmo código que está escrito em C #.

using System; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls;  

namespace XAMLVsCode { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent();  
         
         // Create the StackPanel 
         StackPanel stackPanel = new StackPanel();
         this.Content = stackPanel; 
			
         // Create the TextBlock 
         TextBlock textBlock = new TextBlock(); 
         textBlock.Text = "Welcome to XAML Tutorial"; 
         textBlock.Height = 20;
         textBlock.Width = 200; 
         textBlock.Margin = new Thickness(5); 
         stackPanel.Children.Add(textBlock);  
			
         // Create the Button 
         Button button = new Button(); 
         button.Content = "OK"; 
         button.Height = 20; 
         button.Width = 50; 
         button.Margin = new Thickness(20); 
         stackPanel.Children.Add(button); 
      } 
   }
}

Quando o código acima for compilado e executado, ele produzirá a seguinte saída. Observe que é exatamente igual à saída do código XAML.

Agora você pode ver como é simples usar e entender o XAML.

Neste capítulo, escreveremos o mesmo exemplo em VB.Net para que aqueles que estão familiarizados com o VB.Net também possam entender as vantagens do XAML.

Vamos dar uma olhada no mesmo exemplo novamente, que é escrito em XAML -

<Window x:Class = "XAMLVsCode.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <TextBlock Text = "Welcome to XAML Tutorial with VB.net" Height = "20" Width = "220" Margin = "5"/> 
      <Button Content = "Ok" Height = "20" Width = "60" Margin = "5"/> 
   </StackPanel> 
	
</Window>

Neste exemplo, criamos um painel de pilha com um botão e um bloco de texto e definimos algumas das propriedades do botão e do bloco de texto, como Altura, Largura e Margem. Quando o código acima for compilado e executado, ele produzirá a seguinte saída -

Agora olhe para o mesmo código que está escrito em VB.Net -

Public Class MainWindow
   Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) 
      Dim panel As New StackPanel() 
      panel.Orientation = Orientation.Vertical 
      Me.Content = panel 
      Dim txtInput As New TextBlock 
		
      txtInput.Text = "Welcome to XAML Tutorial with VB.net" 
      txtInput.Width = 220 
      txtInput.Height = 20 
      txtInput.Margin = New Thickness(5) 
		
      panel.Children.Add(txtInput)  
      Dim btn As New Button()
		
      btn.Content = "Ok" 
      btn.Width = 60 
      btn.Height = 20 
      btn.Margin = New Thickness(5) 
		
      panel.Children.Add(btn)
   End Sub 
End Class

Quando o código acima é compilado e executado, a saída é exatamente igual à saída do código XAML.

Agora você pode visualizar como é simples trabalhar com XAML em comparação com VB.Net.

No exemplo acima, vimos que o que podemos fazer em XAML também pode ser feito em outras linguagens procedurais, como C # e VB.Net.

Vamos dar uma olhada em outro exemplo em que usaremos XAML e VB.Net. Vamos projetar uma GUI em XAML e o comportamento será implementado em VB.Net.

Neste exemplo, um botão é adicionado à janela principal. Quando o usuário clica neste botão, ele exibe uma mensagem na caixa de mensagem. Aqui está o código em XAML no qual um objeto de botão é declarado com algumas propriedades.

<Window x:Class="MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button Name = "btn" HorizontalAlignment = "Center" Width = "60" Height = "30" Content = "Click Me" /> 
   </Grid> 
	
</Window>

No VB.Net, o evento de clique de botão (comportamento) é implementado. Este evento exibe a mensagem na caixa de mensagem.

Public Class MainWindow
   Private Sub btn_Click(sender As Object, e As RoutedEventArgs) Handles btn.Click 
      MessageBox.Show("Button is Clicked") 
   End Sub 
End Class

Quando o código acima for compilado e executado, será exibida a seguinte tela -

Agora clique no botão acima que diz "Click Me". Ele exibirá a seguinte mensagem -

Este capítulo descreverá alguns dos blocos de construção básicos e importantes dos aplicativos XAML. Vai explicar como

  • para criar e inicializar um objeto,
  • um objeto pode ser modificado facilmente usando recursos, estilos e modelos,
  • para tornar um objeto interativo usando transformações e animações.

Objetos

XAML é uma linguagem tipicamente declarativa que pode criar e instanciar objetos. É outra forma de descrever objetos baseados em XML, ou seja, quais objetos precisam ser criados e como devem ser inicializados antes da execução de um programa. Objetos podem ser

  • Recipientes (painel de pilha, painel de encaixe)
  • Elementos / controles da interface do usuário (botão, caixa de texto etc.)
  • Dicionários de recursos

Recursos

Os recursos são normalmente definições conectadas a algum objeto que você antecipa usar mais de uma vez. É a capacidade de armazenar dados localmente para controles ou para a janela atual ou globalmente para todos os aplicativos.

Estilos

A estrutura XAML fornece várias estratégias para personalizar e personalizar a aparência de um aplicativo. Os estilos nos dão a flexibilidade de definir algumas propriedades de um objeto e reutilizar essas configurações específicas em vários objetos para uma aparência consistente.

  • Em estilos, você pode definir apenas as propriedades existentes de um objeto, como Altura, Largura, Tamanho da fonte, etc.
  • Apenas o comportamento padrão de um controle pode ser especificado.
  • Várias propriedades podem ser adicionadas a um estilo.

No primeiro diagrama, você pode ver que as mesmas propriedades de altura e largura são definidas para todos os três botões separadamente; mas no segundo diagrama, você pode ver que a altura e a largura, que são iguais para todos os botões, são adicionadas a um estilo e, em seguida, esse estilo é associado a todos os botões.

Modelos

Um modelo descreve a aparência geral e a aparência visual de um controle. Para cada controle, há um modelo padrão associado a ele que dá a aparência a esse controle. No XAML, você pode criar facilmente seus próprios modelos quando quiser personalizar o comportamento visual e a aparência visual de um controle.

Na captura de tela a seguir, existem dois botões, um é com o modelo e o outro é o botão padrão.

Agora, quando você passa o mouse sobre o botão, ele também muda a cor conforme mostrado abaixo.

Com os modelos, você pode acessar mais partes de um controle do que estilos. Você pode especificar o comportamento existente e o novo de um controle.

Animações e transformações

Animações e transformações dentro do Windows Runtime podem melhorar seu aplicativo XAML criando interatividade e movimento. Você pode integrar facilmente a aparência interativa em seu aplicativo XAML usando as animações da biblioteca de animação do Windows Runtime. Animações são usadas

  • para aprimorar a interface do usuário ou torná-la mais atraente.
  • para atrair a atenção do usuário para uma mudança.

Na captura de tela a seguir, você pode ver um quadrado -

Quando você passa o mouse sobre este quadrado, ele se expande em todas as direções conforme mostrado abaixo.

A estrutura de interface do usuário XAML oferece uma ampla biblioteca de controles que oferece suporte ao desenvolvimento de interface do usuário para Windows. Alguns deles possuem uma representação visual como Button, Textbox, TextBlock, etc .; enquanto outros controles são usados ​​como contêineres para outros controles ou conteúdo, por exemplo, imagens. Todos os controles XAML são herdados deSystem.Windows.Controls.Control.

A hierarquia de herança completa de controles é a seguinte -

Aqui está a lista de controles que discutiremos um por um neste capítulo.

Sr. Não. Controles e descrição
1 Botão

Um controle que responde à entrada do usuário.

2 Calendário

Representa um controle que permite a um usuário selecionar uma data usando uma exibição de calendário visual.

3 CheckBox

Um controle que um usuário pode selecionar ou limpar.

4 Caixa combo

Uma lista suspensa de itens que um usuário pode selecionar.

5 Menu contextual

Obtém ou define o elemento do menu de contexto que deve aparecer sempre que o menu de contexto é solicitado por meio de uma interface do usuário (IU) de dentro desse elemento.

6 Grade de dados

Representa um controle que exibe dados em uma grade personalizável.

7 DatePicker

Um controle que permite ao usuário selecionar uma data.

8 Diálogos

Um aplicativo também pode exibir janelas adicionais para o usuário coletar ou exibir informações importantes.

9 GridView

Um controle que apresenta uma coleção de itens em linhas e colunas que podem rolar horizontalmente.

10 Imagem

Um controle que apresenta uma imagem.

11 ListBox

Um controle que apresenta uma lista embutida de itens que o usuário pode selecionar.

12 Menus

Representa um controle de menu do Windows que permite organizar hierarquicamente elementos associados a comandos e manipuladores de eventos.

13 PasswordBox

Um controle para inserir senhas.

14 Aparecer

Exibe o conteúdo acima do conteúdo existente, dentro dos limites da janela do aplicativo.

15 Barra de progresso

Um controle que indica o progresso exibindo uma barra.

16 ProgressRing

Um controle que indica o progresso indeterminado exibindo um anel.

17 Botao de radio

Um controle que permite ao usuário selecionar uma única opção de um grupo de opções.

18 RichEditBox

Um controle que permite ao usuário editar documentos de rich text com conteúdo como texto formatado, hiperlinks e imagens.

19 ScrollViewer

Um controle de contêiner que permite ao usuário deslocar e aplicar zoom em seu conteúdo.

20 Caixa de pesquisa

Um controle que permite a um usuário inserir consultas de pesquisa.

21 Slider

Um controle que permite ao usuário selecionar a partir de uma gama de valores movendo um controle Thumb ao longo de uma trilha.

22 TextBlock

Um controle que exibe texto.

23 TimePicker

Um controle que permite ao usuário definir um valor de hora.

24 ToggleButton

Um botão que pode ser alternado entre 2 estados.

25 Dica de ferramenta

Uma janela pop-up que exibe informações sobre um elemento.

26 Janela

A janela raiz que fornece a opção de minimizar / maximizar, barra de título, borda e botão Fechar.

Neste capítulo, discutiremos todos esses controles com implementação.

O layout dos controles é muito importante e crítico para a usabilidade do aplicativo. É necessário organizar um grupo de elementos da GUI em seu aplicativo. Existem alguns pontos importantes a serem considerados ao selecionar painéis de layout;

  • Posições dos elementos filhos.
  • Tamanhos dos elementos filhos.
  • Sobreposição de elementos filho sobrepostos uns sobre os outros.

A disposição fixa dos controles em pixels não funciona quando um aplicativo é usado em diferentes resoluções de tela. O XAML fornece um rico conjunto de painéis de layout integrados para organizar os elementos da GUI de maneira apropriada. Alguns dos painéis de layout mais comumente usados ​​e populares são os seguintes -

Sr. Não Painéis e descrição
1 StackPanel

O painel de pilha é um painel de layout simples e útil em XAML. Em um painel de pilha, os elementos filho podem ser organizados em uma única linha, horizontal ou verticalmente, com base na propriedade de orientação.

2 WrapPanel

Em WrapPanel, os elementos filhos são posicionados em ordem sequencial da esquerda para a direita ou de cima para baixo com base na propriedade de orientação.

3 DockPanel

DockPanel define uma área para organizar os elementos filhos em relação uns aos outros, horizontal ou verticalmente. Com o DockPanel, você pode facilmente encaixar os elementos filhos nas partes superior, inferior, direita, esquerda e central com a propriedade Dock.

4 CanvasPanel

O painel Canvas é o painel de layout básico no qual os elementos filho podem ser posicionados explicitamente usando coordenadas que são relativas ao Canvas em qualquer lado, como esquerdo, direito, superior e inferior.

5 GridPanel

Um painel de grade fornece uma área flexível que consiste em linhas e colunas. Em uma grade, os elementos filhos podem ser organizados em uma forma tabular.

O conceito geral de eventos em XAML é semelhante a eventos em outras linguagens de programação populares, como .NET e C ++. No XAML, todos os controles expõem alguns eventos para que possam ser inscritos para fins específicos.

Sempre que um evento ocorre, o aplicativo será notificado e o programa pode reagir a eles, por exemplo, botões de fechamento são usados ​​para fechar um diálogo.

Existem muitos tipos de eventos que podem ser inscritos para diferentes comportamentos de um aplicativo com base nos requisitos desse aplicativo, mas os eventos mais comumente usados ​​são aqueles relacionados ao mouse e teclado, como,

  • Click
  • MouseDown
  • MouseEnter
  • MouseLeave
  • MouseUp
  • KeyDown
  • KeyUp

Neste capítulo, usaremos alguns dos eventos básicos e mais comumente usados ​​para entender como um evento de um controle específico pode ser vinculado ao código por trás de onde o comportamento será implementado, dependendo do que o usuário deseja fazer quando um evento específico ocorre.

Vamos dar uma olhada em um exemplo simples de um evento de clique de botão. A seguir, é fornecida a implementação XAML para o controle Button, que é criado e inicializado com algumas propriedades e um evento Click (Click = "OnClick").

<Window x:Class = "XAMLEventHandling.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <Button x:Name = "button1" Content = "Click" Click = "OnClick" 
         Width = "150" Height = "30" HorizontalAlignment = "Center" /> 
   </Grid>
   
</Window>

Sempre que este botão for clicado, ele irá disparar um OnClickevento e você pode adicionar qualquer tipo de comportamento como uma resposta ao clique. Vamos dar uma olhada na implementação do evento OnClick que mostrará uma mensagem quando este botão for clicado.

using System; 
using System.Windows; 
using System.Windows.Controls;  

namespace XAMLEventHandling {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void OnClick(object sender, RoutedEventArgs e) { 
         MessageBox.Show("Button is clicked!"); 
      } 
   }
}

Quando você compila e executa o código acima, ele irá produzir a seguinte saída -

Ao clicar no botão, o evento click (OnClick) será disparado e a seguinte mensagem será exibida.

Agora, vamos dar uma olhada em um exemplo um pouco complexo onde vários eventos são tratados.

Exemplo

O exemplo a seguir contém uma caixa de texto com ContextMenu que manipula o texto dentro da caixa de texto.

O código XAML a seguir cria um TextBox, um ContextMenu e MenuItems com algumas propriedades e eventos, como Checked, Unchecked e Click.

<Window x:Class = "XAMLContextMenu.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid> 
      <TextBox Name = "textBox1" TextWrapping = "Wrap" Margin = "10" Grid.Row = "7"> 
         Hi, this is XAML tutorial. 
         <TextBox.ContextMenu>
         
            <ContextMenu>
               <MenuItem Header = "_Bold" IsCheckable = "True" 
                  Checked = "Bold_Checked" Unchecked = "Bold_Unchecked" /> 
               <MenuItem Header = "_Italic" IsCheckable = "True" 
                  Checked = "Italic_Checked" Unchecked = "Italic_Unchecked" /> 
               <Separator /> 
               <MenuItem Header = "Increase Font Size" Click = "IncreaseFont_Click" />
               <MenuItem Header = "_Decrease Font Size" Click = "DecreaseFont_Click" /> 
            </ContextMenu> 
				
         </TextBox.ContextMenu>
      </TextBox>
   </Grid> 
	
</Window>

Aqui está a implementação em C # para os diferentes eventos que serão disparados sempre que um item de menu for marcado, desmarcado ou clicado.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data;  

namespace XAMLContextMenu { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary>
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void Bold_Checked(object sender, RoutedEventArgs e) { 
         textBox1.FontWeight = FontWeights.Bold; 
      }
      private void Bold_Unchecked(object sender, RoutedEventArgs e) { 
         textBox1.FontWeight = FontWeights.Normal; 
      }
      private void Italic_Checked(object sender, RoutedEventArgs e) { 
         textBox1.FontStyle = FontStyles.Italic; 
      }
      private void Italic_Unchecked(object sender, RoutedEventArgs e) { 
         textBox1.FontStyle = FontStyles.Normal; 
      }
      private void IncreaseFont_Click(object sender, RoutedEventArgs e) { 
         if (textBox1.FontSize < 18) { 
            textBox1.FontSize += 2; 
         } 
      }
      private void DecreaseFont_Click(object sender, RoutedEventArgs e) { 
         if (textBox1.FontSize > 10) { 
            textBox1.FontSize -= 2; 
         } 
      }
   }
}

Quando você compila e executa o código acima, ele irá produzir a seguinte saída -

Recomendamos que você execute o código de exemplo acima e experimente alguns outros eventos.

Eventos

Sr. Não. Controles e descrição
1

Checked

Dispara quando um ToggleButton é verificado. (Herdado de ToggleButton)

2

Click

Ocorre quando um controle de botão é clicado. (Herdado de ButtonBase)

3

ContextMenuClosing

Ocorre antes de qualquer menu de contexto no elemento ser fechado. (Herdado de FrameworkElement.)

4

ContextMenuOpening

Ocorre quando qualquer menu de contexto no elemento é aberto. (Herdado de FrameworkElement.)

5

DataContextChanged

Ocorre quando o valor da propriedade FrameworkElement.DataContext é alterado. (Herdado de FrameworkElement)

6

DragEnter

Ocorre quando o sistema de entrada relata um evento de arrastar subjacente com este elemento como o destino. (Herdado de UIElement).

7

DragLeave

Ocorre quando o sistema de entrada relata um evento de arrastar subjacente com este elemento como origem. (Herdado de UIElement)

8

DragOver

Ocorre quando o sistema de entrada relata um evento de arrastar subjacente com este elemento como o alvo potencial para soltar. (Herdado de UIElement)

9

DragStarting

Ocorre quando uma operação de arrastar é iniciada. (Herdado de UIElement)

10

DropCompleted

Ocorre quando uma operação de arrastar e soltar é encerrada. (Herdado de UIElement)

11

DropDownClosed

Ocorre quando a parte suspensa da ComboBox é fechada.

12

DropDownOpened

Ocorre quando a parte suspensa da ComboBox é aberta.

13

GotFocus

Ocorre quando um UIElement recebe o foco. (Herdado de UIElement)

14

Holding

Ocorre quando uma interação de espera não tratada de outra forma ocorre na área de teste de clique deste elemento. (Herdado de UIElement)

15

Intermediate

Dispara quando o estado de um ToggleButton é alterado para o estado indeterminado. (Herdado de ToggleButton)

16

IsEnabledChanged

Ocorre quando a propriedade IsEnabled é alterada. (Herdado do controle)

17

KeyDown

Ocorre quando uma tecla do teclado é pressionada enquanto o UIElement está em foco. (Herdado de UIElement)

18

KeyUp

Ocorre quando uma tecla do teclado é liberada enquanto o UIElement está em foco. (Herdado de UIElement)

19

LostFocus

Ocorre quando um UIElement perde o foco. (Herdado de UIElement)

20

ManipulationCompleted

Ocorre quando uma manipulação no UIElement é concluída. (Herdado de UIElement)

21

ManipulationDelta

Ocorre quando o dispositivo de entrada muda de posição durante uma manipulação. (Herdado de UIElement)

22

ManipulationInertiaStarting

Ocorre quando o dispositivo de entrada perde contato com o objeto UIElement durante uma manipulação e a inércia começa. (Herdado de UIElement)

23

ManipulationStarted

Ocorre quando um dispositivo de entrada começa uma manipulação no UIElement. (Herdado de UIElement)

24

ManipulationStarting

Ocorre quando o processador de manipulação é criado pela primeira vez. (Herdado de UIElement)

25

SelectionChanged

Ocorre quando a seleção de texto é alterada.

26

SizeChanged

Ocorre quando a propriedade ActualHeight ou ActualWidth altera o valor em um FrameworkElement. (Herdado de FrameworkElement)

27

Unchecked

Ocorre quando um ToggleButton está desmarcado. (Herdado de ToggleButton)

28

ValueChanged

Ocorre quando o valor do intervalo muda. (Herdado de RangeBase)

A vinculação de dados é um mecanismo em aplicativos XAML que fornece uma maneira simples e fácil para aplicativos do Windows Runtime usando classes parciais para exibir e interagir com dados. O gerenciamento de dados é totalmente separado da forma como os dados são exibidos neste mecanismo.

A vinculação de dados permite o fluxo de dados entre os elementos da IU e o objeto de dados na interface do usuário. Quando uma ligação é estabelecida e os dados ou seu modelo de negócios são alterados, ele refletirá as atualizações automaticamente nos elementos da IU e vice-versa. Também é possível vincular, não a uma fonte de dados padrão, mas sim a outro elemento na página. A vinculação de dados pode ser de dois tipos -

  • Vinculação de dados unilateral
  • Ligação de dados bidirecional

Vinculação de dados unilateral

Na vinculação unilateral, os dados são vinculados de sua origem (ou seja, o objeto que contém os dados) ao seu destino (ou seja, o objeto que exibe os dados).

Vamos dar uma olhada em um exemplo simples de vinculação de dados unilateral. O código XAML a seguir cria quatro blocos de texto com algumas propriedades.

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid>
      <StackPanel Name = "Display">
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> 
            <TextBlock Text = "Name: " Margin = "10" Width = "100" /> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Name}" />
         </StackPanel> 
		
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> 
            <TextBlock Text = "Title: " Margin = "10" Width = "100" /> 
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Title}" /> 
         </StackPanel>
      </StackPanel>
   </Grid> 
	
</Window>

As propriedades de texto de dois blocos de texto são definidas como “Nome” e “Título” estaticamente, enquanto os outros dois blocos de texto As propriedades de texto são vinculadas a “Nome” e “Título”, que são variáveis ​​de classe da classe Funcionário mostradas abaixo.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
 
namespace DataBindingOneWay {
   public class Employee {
      public string Name { get; set; } 
      public string Title { get; set; }  
		
      public static Employee GetEmployee() {
         var emp = new Employee() { 
            Name = "Ali Ahmed", Title = "Developer" 
         }; 
         return emp; 
      }
   }
}

Nesta classe, temos apenas duas variáveis, Name e Titlee um método estático no qual o objeto Employee é inicializado, que retornará esse objeto Employee. Portanto, estamos vinculando a uma propriedade, Nome e Título, mas não selecionamos a qual objeto essa propriedade pertence. A maneira mais fácil é atribuir um objeto a DataContext cujas propriedades estamos vinculando no seguinte código C # -

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace DataBindingOneWay { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      } 
   }
}

Vamos executar este aplicativo e você poderá ver imediatamente em nossa MainWindow que vinculamos com êxito o Nome e o Título desse objeto Funcionário.

Vinculação de dados bidirecional

Na ligação bidirecional, o usuário pode modificar os dados por meio da interface do usuário e ter esses dados atualizados na fonte. Se a fonte muda enquanto o usuário está olhando para a visão, você pode querer atualizar a visão.

Exemplo

Vamos dar uma olhada no exemplo a seguir, no qual uma combobox com três itens de combobox e uma caixa de texto são criadas com algumas propriedades. Neste exemplo, não temos nenhuma fonte de dados padrão, mas os elementos da IU estão vinculados a outros elementos da IU.

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel>
      <ComboBox Name = "comboBox"  Margin = "50" Width = "100"> 
         <ComboBoxItem Content = "Green" /> 
         <ComboBoxItem Content = "Yellow" IsSelected = "True" /> 
         <ComboBoxItem Content = "Orange" /> 
      </ComboBox>
		
      <TextBox  Name = "textBox" Margin = "50" 
         Width = "100" Height = "23" VerticalAlignment = "Top" 
         Text  = "{Binding ElementName = comboBox, Path = SelectedItem.Content, 
         Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox>
   </StackPanel> 
	
</Window>

Quando você compila e executa o código acima, ele produzirá a seguinte saída. Quando o usuário seleciona um item da caixa de combinação, o texto da caixa de texto e a cor de fundo são atualizados de acordo.

Da mesma forma, quando o usuário digita um nome de cor válido na caixa de texto, a caixa de combinação e a cor de fundo da caixa de texto também são atualizadas.

Em aplicativos XAML, as extensões de marcação são um método / técnica para obter um valor que não é um objeto XAML específico nem um tipo primitivo. As extensões de marcação podem ser definidas abrindo e fechando chaves e dentro dessas chaves, o escopo da extensão de marcação é definido.

A vinculação de dados e os recursos estáticos são extensões de marcação. Existem algumas extensões de marcação XAML predefinidas emSystem.xaml que pode ser usado.

Vamos dar uma olhada em um exemplo simples onde StaticResources A extensão de marcação é usada, que é uma extensão de marcação XAML predefinida.

O código XAML a seguir cria dois blocos de texto com algumas propriedades e seu primeiro plano é definido em Window.Resources.

<Window x:Class = "XAMLStaticResourcesMarkupExtension.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Window.Resources> 
      <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
   </Window.Resources> 
	
   <Grid> 
      <StackPanel Orientation = "Vertical"> 
         <TextBlock Foreground = "{StaticResource myBrush}" Text = "First Name" 
            Width = "100" Margin = "10" /> 
         <TextBlock Foreground = "{StaticResource myBrush}" Text = "Last Name" 
            Width = "100" Margin = "10" /> 
      </StackPanel> 
   </Grid> 
	
</Window>

Dentro Window.Resources, você pode ver x:Key é usado para identificar exclusivamente os elementos que são criados e referenciados em um dicionário definido em XAML para identificar um recurso em um dicionário de recursos.

Quando você compila e executa o código acima, ele produzirá a seguinte MainWindow. Você pode ver os dois blocos de texto com a cor azul do primeiro plano.

Em XAML, as extensões de marcação personalizadas também podem ser definidas herdando a classe MarkupExtension e substituindo o método ProvideValue, que é um método abstrato na classe MarkupExtension.

Vamos dar uma olhada em um exemplo simples de extensão de marcação personalizada.

<Window x:Class = "XAMLMarkupExtension.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:my = "clr-namespace:XAMLMarkupExtension" 
   Title = "MainWindow" Height = "350" Width = "525"> 
	
   <Grid> 
      <Button Content = "{my:MyMarkupExtension FirstStr = Markup, SecondStr = Extension}" 
         Width = "200" Height = "20" /> 
   </Grid> 
	
</Window>

No código XAML acima, um botão é criado com algumas propriedades e para o valor do conteúdo, uma extensão de marcação personalizada (my:MyMarkupExtension) foi usado com dois valores “Markup” e “Extension” que são atribuídos a FirstStr e SecondStr respectivamente.

Na verdade, MyMarkupExtensioné uma classe que é derivada MarkupExtensionconforme mostrado abaixo na implementação do C #. Esta classe contém duas variáveis ​​de string, FirstStr e SecondStr, que são concatenadas e retornam essa string do método ProvideValue para o Conteúdo de um botão.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;
 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Markup; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes;  

namespace XAMLMarkupExtension { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window { 
      public MainWindow() { 
         InitializeComponent(); 
      } 
   }
   public class MyMarkupExtension : MarkupExtension { 
      public MyMarkupExtension() { } 
      public String FirstStr { get; set; } 
      public String SecondStr { get; set; }  
		
      public override object ProvideValue(IServiceProvider serviceProvider) { 
        return FirstStr + " " + SecondStr; 
      } 
   }
}

Vamos executar este aplicativo e você pode ver imediatamente em nossa MainWindow que a "extensão de marcação" foi usada com sucesso como o conteúdo do botão.

Uma propriedade de dependência é um tipo específico de propriedade em que o valor é seguido por um sistema de propriedades avançado que também faz parte do Aplicativo do Windows Runtime. Uma classe que define uma propriedade de dependência deve ser herdada da classe DependencyObject.

Muitas das classes de controle da IU que são usadas em XAML são derivadas da classe DependencyObject e oferecem suporte a propriedades de dependência. O código XAML a seguir cria um botão com algumas propriedades.

<Window x:Class = "XAMLDependencyProperty.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:XAMLDependencyProperty"
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <Button Height = "40" Width = "175" Margin = "10" Content = "Dependency Property">
         <Button.Style>
            <Style TargetType = "{x:Type Button}">
               <Style.Triggers> 
                  <Trigger Property = "IsMouseOver" Value = "True">
                     <Setter Property = "Foreground" Value = "Red" />
                  </Trigger>
               </Style.Triggers>
            </Style>
         </Button.Style>
      </Button>
   </Grid>
   
</Window>

A extensão de marcação x: Type em XAML tem uma funcionalidade semelhante, como typeof () em C #. É usado quando os atributos são especificados que assumem o tipo do objeto, como <Style TargetType = "{x: Type Button}">

Quando você compila e executa o código acima, ele produzirá a seguinte MainWindow. Quando o mouse estiver sobre o botão, ele mudará a cor do primeiro plano do botão. Quando o mouse sair do botão, ele voltará à cor original.

A principal diferença entre propriedades de dependência e outras propriedades CLR são -

  • As propriedades CLR podem ler / gravar diretamente do membro privado de uma classe usando getter e setter. No caso de propriedades de dependência, ele não é armazenado em um objeto local.

  • As propriedades de dependência são armazenadas em um dicionário de pares de chave / valor que é fornecido pela classe DependencyObject.

  • Ele também economiza muita memória porque armazena a propriedade quando alterada.

  • Ele também pode ser vinculado a XAML.

No .NET framework, as propriedades de dependência personalizadas também podem ser definidas. Aqui estão as etapas para definir a propriedade de dependência personalizada em C #.

  • Declare e registre sua propriedade de dependência com o registro de chamadas do sistema.

  • Fornece o setter e getter para a propriedade.

  • Defina um manipulador estático para lidar com quaisquer mudanças que ocorram globalmente.

  • Defina um manipulador de instância para lidar com qualquer alteração que ocorra nessa instância específica.

A seguir é fornecido o código em C # para a propriedade de dependência definida para definir a propriedade SetText do controle do usuário.

using System; 
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication3 {
   /// <summary> 
      /// Interaction logic for UserControl1.xaml 
   /// </summary> 
	
   public partial class UserControl1 : UserControl {
      public UserControl1() {
         InitializeComponent();
      }
      public static readonly DependencyProperty
         SetTextProperty = DependencyProperty.Register("SetText", typeof(string), 
         typeof(UserControl1), new PropertyMetadata("", 
         new PropertyChangedCallback(OnSetTextChanged)));
      public string SetText {
         get {return(string) GetValue(SetTextProperty); }
         set {SetValue(SetTextProperty, value);}
      }
      private static void OnSetTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
         UserControl1 UserControl1Control = d as UserControl1;
         UserControl1Control.OnSetTextChanged(e);
      }
      private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) {
         tbTest.Text = e.NewValue.ToString();
      }
   }
}

Aqui está o arquivo XAML no qual o TextBlock é definido como um controle de usuário e a propriedade Text será atribuída a ele pela propriedade de dependência SetText.

O código XAML a seguir cria um controle de usuário com a inicialização de sua propriedade de dependência SetText e algumas outras propriedades.

<Window x:Class = "WpfApplication3.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:views = "clr-namespace:WpfApplication3" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <views:UserControl1 SetText = "Hellow World" />
   </Grid>
	
</Window>

Vamos executar este aplicativo e você pode ver imediatamente em nossa MainWindow que a propriedade de dependência para controle de usuário foi usada com sucesso como um Texto.

Os recursos são normalmente definições conectadas a algum objeto que você antecipa usar mais de uma vez. Ele tem a capacidade de armazenar dados localmente para controles ou para a janela atual ou globalmente para todos os aplicativos.

Definir um objeto como recurso nos permite acessá-lo de outro lugar. Portanto, permite a reutilização. Os recursos são definidos em dicionários de recursos e qualquer objeto pode ser definido como um recurso, tornando-o efetivamente um ativo compartilhável. Uma chave exclusiva é especificada para o recurso XAML e com essa chave, ela pode ser referenciada usando uma extensão de marcação StaticResource.

Vamos dar uma olhada em um exemplo simples novamente em que dois blocos de texto são criados com algumas propriedades e sua cor de primeiro plano é definida em Window.Resources.

<Window x:Class = "XAMLResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources> 
      <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
   </Window.Resources>  
	
   <StackPanel Orientation = "Vertical"> 
      <TextBlock Foreground = "{StaticResource myBrush}" 
         Text = "First Name" Width = "100" Margin = "10" /> 
      <TextBlock Foreground = "{StaticResource myBrush}" 
         Text = "Last Name" Width = "100" Margin = "10" /> 
   </StackPanel> 
	
</Window>

Quando o código acima for compilado e executado, ele produzirá a seguinte MainWindow. Você pode ver dois blocos de texto com a cor azul do primeiro plano. A vantagem do recurso é que, se houver vários blocos de texto e você quiser alterar sua cor de fundo, será necessário apenas alterá-la no dicionário de recursos.

Escopo do Recurso

Os recursos são definidos em dicionários de recursos, mas existem vários lugares onde um dicionário de recursos pode ser definido. No exemplo acima, um dicionário de recursos é definido no nível da janela / página. Em qual dicionário um recurso é definido limita imediatamente o escopo desse recurso. Portanto, o escopo, ou seja, onde você pode usar o recurso, depende de onde você o definiu.

  • Defina o recurso no dicionário de recursos de uma grade e ele é acessível apenas por aquela grade e por seus elementos filhos.

  • Defina-o em uma janela / página e é acessível por todos os elementos dessa janela / página.

  • A raiz do aplicativo pode ser encontrada no dicionário de recursos App.xaml. É a raiz de nosso aplicativo, portanto, os recursos definidos aqui têm como escopo o aplicativo completo.

No que diz respeito ao escopo do recurso, os mais frequentemente são o nível do aplicativo, o nível da página e um nível de elemento específico, como uma grade, StackPanel etc.

Dicionários de recursos

Dicionários de recursos em aplicativos XAML implicam dicionários de recursos em arquivos separados. Ele é seguido em quase todos os aplicativos XAML. Definir recursos em arquivos separados pode ter as seguintes vantagens -

  • Separação entre definir recursos no dicionário de recursos e o código relacionado à IU.

  • Definir todos os recursos em um arquivo separado, como App.xaml, os tornaria disponíveis em todo o aplicativo.

Então, como podemos definir nossos recursos em um dicionário de recursos em um arquivo separado? Bem, é muito fácil, basta adicionar um novo dicionário de recursos por meio do Visual Studio pelas seguintes etapas -

  • Em sua solução, adicione uma nova pasta e nomeie-a ResourceDictionaries.

  • Clique com o botão direito nesta pasta e selecione Dicionário de Recursos em Adicionar item de submenu e nomeie-o DictionaryWithBrush.xaml

Vamos dar uma olhada no mesmo aplicativo; apenas o dicionário de recursos agora está definido no nível do aplicativo.

Aqui está o código XAML para MainWindow.xaml.

<Window x:Class = "XAMLResources.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel Orientation = "Vertical"> 
      <TextBlock Foreground = "{StaticResource myBrush}" Text = "First Name" 
         Width = "100" Margin = "10" /> 
      <TextBlock Foreground = "{StaticResource myBrush}" Text = "Last Name" 
         Width = "100" Margin = "10"/> 
   </StackPanel> 
	
</Window>

Aqui está a implementação em DictionaryWithBrush.xaml -

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> 
	
   <SolidColorBrush Color = "Blue" x:Key = "myBrush"></SolidColorBrush> 
	
</ResourceDictionary>

Aqui está a implementação em app.xaml -

<Application x:Class = "XAMLResources.App" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   StartupUri = "MainWindow.xaml"> 
	
   <Application.Resources> 
      <ResourceDictionary Source = " XAMLResources\ResourceDictionaries\DictionaryWithBrush.xaml" /> 
   </Application.Resources> 
	
</Application>

Quando o código acima for compilado e executado, ele produzirá a seguinte saída -

Recomendamos que você execute o código acima e experimente mais alguns recursos, como cor de fundo, etc.

Um modelo descreve a aparência geral e a aparência visual de um controle. Para cada controle, há um modelo padrão associado a ele que dá a aparência a esse controle.

No XAML, você pode criar facilmente seus próprios modelos quando quiser personalizar o comportamento visual e a aparência visual de um controle. A conectividade entre a lógica e o modelo pode ser obtida por vinculação de dados.

A principal diferença entre estilos e modelos são -

  • Os estilos só podem alterar a aparência do seu controle com as propriedades padrão desse controle.

  • Com os modelos, você pode acessar mais partes de um controle do que estilos. Você também pode especificar o comportamento existente e o novo de um controle.

Existem dois tipos de modelos que são mais comumente usados.

  • Modelo de controle
  • Modelo de Dados

Modelo de controle

O modelo de controle define ou especifica a aparência visual e a estrutura de um controle. Todos os elementos da IU têm algum tipo de aparência e comportamento, por exemplo, Button tem aparência e comportamento. Evento de clique ou evento de passar o mouse são os comportamentos disparados em resposta a um clique e passar o mouse, e também há uma aparência padrão de botão que pode ser alterada pelo modelo de controle.

Vamos dar uma olhada em um exemplo simples novamente no qual dois botões são criados com algumas propriedades. Um está comtemplate e o outro está com o default botão.

<Window x:Class = "TemplateDemo.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Window.Resources>
      <ControlTemplate x:Key = "ButtonTemplate" TargetType = "Button">
         <Grid>
            <Ellipse x:Name = "ButtonEllipse" Height = "100" Width = "150" >
               <Ellipse.Fill> 
                  <LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4"> 
                     <GradientStop Offset = "0" Color = "Red"/>
                     <GradientStop Offset = "1" Color = "Orange"/>
                  </LinearGradientBrush> 
               </Ellipse.Fill>
            </Ellipse>
            <ContentPresenter Content = "{TemplateBinding Content}"
               HorizontalAlignment = "Center" VerticalAlignment = "Center" />
         </Grid>
         <ControlTemplate.Triggers> 
            <Trigger Property = "IsMouseOver" Value = "True">
               <Setter TargetName = "ButtonEllipse" Property = "Fill" >
                  <Setter.Value> 
                     <LinearGradientBrush StartPoint = "0,0.2" EndPoint="0.2,1.4"> 
                        <GradientStop Offset = "0" Color = "YellowGreen"/>
                        <GradientStop Offset = "1" Color = "Gold"/>
                     </LinearGradientBrush> 
                  </Setter.Value> 
               </Setter>
            </Trigger> 
				
            <Trigger Property = "IsPressed" Value = "True"> 
               <Setter Property = "RenderTransform"> 
                  <Setter.Value> 
                     <ScaleTransform ScaleX = "0.8" ScaleY = "0.8" CenterX = "0" CenterY = "0" /> 
                  </Setter.Value> 
               </Setter> 
					
               <Setter Property = "RenderTransformOrigin" Value = "0.5,0.5" /> 
            </Trigger>
         </ControlTemplate.Triggers>
      </ControlTemplate> 
   </Window.Resources>
	
   <StackPanel> 
      <Button Content = "Round Button!" Template = "{StaticResource ButtonTemplate}" 
         Width = "150" Margin = "50" />
      <Button Content = "Default Button!" Height = "40" Width = "150" Margin = "5" /> 
   </StackPanel> 
	
</Window>

Quando o código acima for compilado e executado, ele produzirá a seguinte MainWindow -

Quando você passa o mouse sobre o botão com o modelo personalizado, ele também muda a cor conforme mostrado abaixo -

Modelo de Dados

Um modelo de dados define e especifica a aparência e a estrutura da coleção de dados. Ele fornece a flexibilidade de formatar e definir a apresentação dos dados em qualquer elemento da IU. É usado principalmente em controles de item relacionados a dados, como ComboBox, ListBox, etc.

Vamos dar uma olhada em um exemplo simples de modelo de dados. O código XAML a seguir cria uma caixa de combinação com modelo de dados e blocos de texto.

<Window x:Class = "XAMLDataTemplate.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <Grid VerticalAlignment = "Top">
      <ComboBox Name = "Presidents" ItemsSource = "{Binding}" Height = "30" Width = "400"> 
         <ComboBox.ItemTemplate> 
            <DataTemplate>
               <StackPanel Orientation = "Horizontal" Margin = "2">
                  <TextBlock Text = "Name: " Width = "95" Background = "Aqua" Margin = "2" /> 
                  <TextBlock Text = "{Binding Name}" Width = "95" Background = "AliceBlue" Margin = "2" /> 
                  <TextBlock Text = "Title: " Width = "95" Background = "Aqua" Margin = "10,2,0,2" />
                  <TextBlock Text = "{Binding Title}" Width = "95" Background = "AliceBlue" Margin = "2" /> 
               </StackPanel>
            </DataTemplate>
         </ComboBox.ItemTemplate> 
      </ComboBox> 
   </Grid>
   
</Window>

Aqui está a implementação em C # em que o objeto funcionário é atribuído a DataContext -

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace XAMLDataTemplate { 
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() {
         InitializeComponent(); 
         DataContext = Employee.GetEmployees(); 
      }
   }
}

Aqui está a implementação em C # para a classe Employee -

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Runtime.CompilerServices; 
using System.Text; 
using System.Threading.Tasks;

namespace XAMLDataTemplate { 
   public class Employee : INotifyPropertyChanged {
      private string name; public string Name {
         get { return name; } 
         set { name = value; RaiseProperChanged(); } 
      }
      private string title; public string Title { 
         get { return title; } 
         set { title = value; RaiseProperChanged(); } 
      }
      public static Employee GetEmployee() {
         var emp = new Employee() { 
            Name = "Waqas", Title = "Software Engineer" };
         return emp; 
      }
      public event PropertyChangedEventHandler PropertyChanged;
      private void RaiseProperChanged( [CallerMemberName] string caller = ""){
         if (PropertyChanged != null) { 
            PropertyChanged(this, new PropertyChangedEventArgs(caller)); 
         } 
      }
      public static ObservableCollection<Employee> GetEmployees() {
         var employees = new ObservableCollection<Employee>();
         employees.Add(new Employee() { Name = "Ali", Title = "Developer" }); 
         employees.Add(new Employee() { Name = "Ahmed", Title = "Programmer" });
         employees.Add(new Employee() { Name = "Amjad", Title = "Desiner" });
         employees.Add(new Employee() { Name = "Waqas", Title = "Programmer" }); 
         employees.Add(new Employee() { Name = "Bilal", Title = "Engineer" });
         employees.Add(new Employee() { Name = "Waqar", Title = "Manager" }); 
         return employees; 
      }
   }
}

Quando o código acima for compilado e executado, ele produzirá a seguinte saída. Ele contém uma combobox e quando você clica na combobox, você vê que a coleção de dados que são criados na classe Employee é listada como os itens da combobox.

Recomendamos que você execute o código acima e faça experiências com ele.

A estrutura XAML fornece várias estratégias para personalizar e personalizar a aparência de um aplicativo. Os estilos nos dão a flexibilidade de definir algumas propriedades de um objeto e reutilizar essas configurações específicas em vários objetos para uma aparência consistente.

  • Em estilos, você pode definir apenas as propriedades existentes de um objeto, como Altura, Largura e Tamanho da fonte.

  • Apenas o comportamento padrão de um controle pode ser especificado.

  • Várias propriedades podem ser adicionadas em um único estilo.

Os estilos são usados ​​para dar uma aparência uniforme a um conjunto de controles. Estilos implícitos são usados ​​para aplicar uma aparência a todos os controles de um determinado tipo e simplificar o aplicativo.

Imagine que temos três botões e todos eles têm que ter a mesma aparência - mesma largura e altura, mesmo tamanho de fonte e mesma cor de primeiro plano. Podemos definir todas essas propriedades nos próprios elementos do botão e isso ainda está bem para todos os botões, conforme mostrado no diagrama a seguir.

Mas em um aplicativo da vida real, você normalmente terá muito mais desses que precisam ser exatamente iguais. E não apenas os botões, é claro, você normalmente deseja que seus blocos de texto, caixas de texto e caixas de combinação, etc., tenham a mesma aparência em seu aplicativo. Certamente deve haver uma maneira melhor de conseguir isso - é conhecido comostyling. Você pode pensar em um estilo como uma maneira conveniente de aplicar um conjunto de valores de propriedade a mais de um elemento, conforme mostrado no diagrama a seguir.

Vejamos o exemplo que contém três botões criados em XAML com algumas propriedades.

<Window x:Class = "XAMLStyle.MainWindow" 
   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"
   xmlns:local = "clr-namespace:XAMLStyle" mc:Ignorable = "d" 
   Title = "MainWindow" Height = "350" Width = "604"> 
	
   <StackPanel> 
      <Button Content = "Button1" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/>
      
      <Button Content = "Button2" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/>
      
      <Button Content = "Button3" Height = "30" Width = "80" Foreground = "Blue" 
         FontSize = "12" Margin = "10"/> 
   </StackPanel> 
	
</Window>

Quando você olhar para o código acima, verá que para todos os botões, a altura, a largura, a cor do primeiro plano, o tamanho da fonte e as propriedades da margem permanecem as mesmas. Quando o código acima for compilado e executado, ele exibirá a seguinte saída -

Agora vamos dar uma olhada no mesmo exemplo, mas desta vez, vamos usar style.

<Window x:Class = "XAMLStyle.MainWindow" 
   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"
   xmlns:local = "clr-namespace:XAMLStyle" mc:Ignorable = "d" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources> 
      <Style x:Key = "myButtonStyle" TargetType = "Button">
         <Setter Property = "Height" Value = "30"/> 
         <Setter Property = "Width" Value = "80"/> 
         <Setter Property = "Foreground" Value = "Blue"/> 
         <Setter Property = "FontSize" Value = "12"/> 
         <Setter Property = "Margin" Value = "10"/> 
      </Style>
   </Window.Resources> 
	
   <StackPanel> 
      <Button Content = "Button1" Style = "{StaticResource myButtonStyle}"/>
      <Button Content = "Button2" Style = "{StaticResource myButtonStyle}"/>
      <Button Content = "Button3" Style = "{StaticResource myButtonStyle}"/>
   </StackPanel>
	
</Window>

Os estilos são definidos no dicionário de recursos e cada estilo possui um identificador de chave exclusivo e um tipo de destino. Dentro de <style>, você pode ver que várias tags setter são definidas para cada propriedade que será incluída no estilo.

No exemplo acima, todas as propriedades comuns de cada botão agora são definidas em estilo e, em seguida, o estilo é atribuído a cada botão com uma chave exclusiva, definindo a propriedade de estilo por meio da extensão de marcação StaticResource.

Quando o código acima for compilado e executado, ele produzirá a seguinte janela que é a mesma saída.

A vantagem de fazer assim é imediatamente óbvia. Podemos reutilizar esse estilo em qualquer lugar em seu escopo e, se precisarmos alterá-lo, simplesmente o alteramos uma vez na definição do estilo, em vez de em cada elemento.

Em que nível um estilo é definido limita instantaneamente o escopo desse estilo. Portanto, o escopo, ou seja, onde você pode usar o estilo, depende de onde você o definiu. O estilo pode ser definido nos seguintes níveis -

Sr. Não Níveis e descrição
1 Nível de controle

Definir um estilo no nível de controle só pode ser aplicado a esse controle específico.

2 Nível de Layout

Definir um estilo em qualquer nível de layout só pode ser acessado por esse layout e apenas por seus elementos filho.

3 Nível da janela

A definição de um estilo no nível da janela pode ser acessada por todos os elementos dessa janela.

4 Nível de Aplicação

Definir um estilo no nível do aplicativo torna-o acessível em todo o aplicativo.

Basicamente, um gatilho permite que você altere os valores da propriedade ou execute ações com base no valor de uma propriedade. Assim, basicamente permite que você altere dinamicamente a aparência e / ou comportamento de seu controle sem ter que criar um novo.

Os gatilhos são usados ​​para alterar o valor de qualquer propriedade, quando certas condições são satisfeitas. Os gatilhos geralmente são definidos em um estilo ou na raiz de um documento que são aplicados a esse controle específico. Existem três tipos de gatilhos -

  • Gatilhos de propriedade
  • Gatilhos de dados
  • Gatilhos de eventos

Gatilhos de propriedade

Em disparadores de propriedade, quando ocorre uma mudança em uma propriedade, ela trará uma mudança imediata ou animada em outra propriedade. Por exemplo, você pode usar um disparador de propriedade se quiser alterar a aparência do botão quando o mouse estiver sobre o botão.

Exemplo

O exemplo a seguir demonstra como alterar a cor de primeiro plano de um botão quando o mouse entra em sua região.

<Window x:Class = "XAMLPropertyTriggers.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Window.Resources>
      <Style x:Key = "TriggerStyle" TargetType = "Button">
         <Setter Property = "Foreground" Value = "Blue" />
         <Style.Triggers>
            <Trigger Property = "IsMouseOver" Value = "True">
               <Setter Property = "Foreground" Value = "Green" />
            </Trigger> 
         </Style.Triggers>
      </Style>
   </Window.Resources>
	
   <Grid>
      <Button Width = "100" Height = "70" Style = "{StaticResource TriggerStyle}" 
         Content = "Trigger"/>
   </Grid>
	
</Window>

Quando você compila e executa o código acima, ele irá produzir a seguinte saída -

Quando o mouse entra na região do botão, a cor do primeiro plano muda para verde.

Gatilhos de dados

Um acionador de dados executa alguma ação quando os dados vinculados satisfazem alguma condição. Vamos dar uma olhada no código XAML a seguir, no qual uma caixa de seleção e um bloco de texto são criados com algumas propriedades. Quando a caixa de seleção está marcada, ela mudará a cor do primeiro plano para vermelho.

<Window x:Class = "XAMLDataTrigger.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "Data Trigger" Height = "350" Width = "604">
	
   <StackPanel HorizontalAlignment = "Center">
      <CheckBox x:Name = "redColorCheckBox" Content = "Set red as foreground color" Margin = "20"/>
		
      <TextBlock Name = "txtblock" VerticalAlignment = "Center" 
         Text = "Event Trigger" FontSize = "24" Margin = "20">
         <TextBlock.Style>
            <Style>
               <Style.Triggers>
                  <DataTrigger Binding = "{Binding ElementName = redColorCheckBox, Path = IsChecked}" 
                     Value = "true">
                     <Setter Property = "TextBlock.Foreground" Value = "Red"/>
                     <Setter Property = "TextBlock.Cursor" Value = "Hand" />
                  </DataTrigger>
               </Style.Triggers>
            </Style>
         </TextBlock.Style>
      </TextBlock>
   </StackPanel>
	
</Window>

Quando você compila e executa o código acima, ele irá produzir a seguinte saída -

Quando a caixa de seleção é marcada, a cor de primeiro plano do bloco de texto muda para vermelho.

Gatilhos de eventos

Um gatilho de evento executa alguma ação quando um evento específico é disparado. Geralmente é usado para realizar algumas animações como DoubleAnimation, ColorAnimation, etc. O bloco de código a seguir cria um botão simples. Quando o evento de clique é disparado, ele expande a largura e a altura do botão.

<Window x:Class = "XAMLEventTrigger.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <Button Content = "Click Me" Width = "60" Height = "30">
         <Button.Triggers>
            <EventTrigger RoutedEvent = "Button.Click">
               <EventTrigger.Actions>
                  <BeginStoryboard>
                     <Storyboard>
                     
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Width" Duration = "0:0:4">
                           <LinearDoubleKeyFrame Value = "60" KeyTime = "0:0:0"/>
                           <LinearDoubleKeyFrame Value = "120" KeyTime = "0:0:1"/>
                           <LinearDoubleKeyFrame Value = "200" KeyTime = "0:0:2"/>
                           <LinearDoubleKeyFrame Value = "300" KeyTime = "0:0:3"/>
                        </DoubleAnimationUsingKeyFrames>
							
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty = "Height" Duration = "0:0:4">
                           <LinearDoubleKeyFrame Value = "30" KeyTime = "0:0:0"/>
                           <LinearDoubleKeyFrame Value = "40" KeyTime = "0:0:1"/>
                           <LinearDoubleKeyFrame Value = "80" KeyTime = "0:0:2"/>
                           <LinearDoubleKeyFrame Value = "150" KeyTime = "0:0:3"/>
                        </DoubleAnimationUsingKeyFrames>
							
                     </Storyboard>
                  </BeginStoryboard>
               </EventTrigger.Actions>
            </EventTrigger>
         </Button.Triggers>
      </Button>
   </Grid>
</Window>

Quando você compila e executa o código acima, ele irá produzir a seguinte saída -

Agora, clique no botão e você verá que ele começará a se expandir nas duas dimensões.

Se você estiver familiarizado com a depuração em qualquer linguagem procedural (como C #, C / C ++ etc.) e souber o uso de breake estão esperando o mesmo tipo de depuração em XAML, então você ficará surpreso ao saber que ainda não é possível depurar um código XAML da mesma forma que você costumava depurar qualquer outro código de linguagem procedural. Depurar um aplicativo XAML significa tentar encontrar um erro;

  • Na vinculação de dados, seus dados não aparecem na tela e você não sabe por quê

  • Ou um problema está relacionado a layouts complexos.

  • Ou um problema de alinhamento ou problemas na cor da margem, sobreposições, etc. com alguns modelos extensos como ListBox e caixa de combinação.

A depuração em XAML é algo que você normalmente faz para verificar se as ligações funcionam e, se não estiverem, para verificar o que está errado. Infelizmente, não é possível definir pontos de interrupção em associações XAML, exceto no Silverlight, mas podemos usar a janela Saída para verificar se há erros de associação de dados. Vamos dar uma olhada no código XAML a seguir para encontrar o erro na vinculação de dados.

<Window x:Class = "DataBindingOneWay.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <Grid>
      <StackPanel Name = "Display">
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0">
            <TextBlock Text = "Name: " Margin = "10" Width = "100"/>
            <TextBlock Margin = "10" Width = "100" Text = "{Binding FirstName}"/>
         </StackPanel>
			
         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0">
            <TextBlock Text = "Title: " Margin = "10" Width = "100"/>
            <TextBlock Margin = "10" Width="100" Text = "{Binding Title}" />
         </StackPanel>
      </StackPanel>
   </Grid>
	
</Window>

As propriedades de texto dos dois blocos de texto são definidas como “Nome” e “Título” estaticamente, enquanto as outras propriedades de texto de dois blocos de texto são vinculadas a “Nome” e “Título”. Mas as variáveis ​​de classe são consideradas intencionalmente como Nome e Título na classe Funcionário, que são nomes de variáveis ​​incorretos. Vamos agora tentar entender onde podemos encontrar esse tipo de erro quando a saída desejada não é mostrada.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;

namespace DataBindingOneWay {
   public class Employee {
      public string Name { get; set; } 
      public string Title { get; set; }
		
      public static Employee GetEmployee() {
         var emp = new Employee() {
            Name = "Ali Ahmed", 
            Title = "Developer"
         };
         return emp; 
      }
   }
}

Aqui está a implementação da classe MainWindow no código C # -

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace DataBindingOneWay {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() {
         InitializeComponent(); 
         DataContext = Employee.GetEmployee(); 
      }
   }
}

Vamos executar este aplicativo e você pode ver imediatamente em nossa MainWindow que vinculamos com sucesso ao Title desse objeto Employee, mas o nome não está vinculado.

Para verificar o que aconteceu com o nome, vamos dar uma olhada na janela de saída onde muitos logs são gerados.

A maneira mais fácil de encontrar um erro é apenas pesquisar o erro e você encontrará o erro mencionado abaixo que diz “Erro de caminho BindingExpression: propriedade 'FirstName' não encontrada no 'objeto' '' Funcionário”

System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName'
   property not found on 'object' ''Employee' (HashCode = 11611730)'.
BindingExpression:Path = FirstName; 
DataItem = 'Employee' (HashCode = 11611730); target element is 'TextBlock' (Name = ''); 
target property is 'Text' (type 'String')

O que indica claramente que FirstName não é membro da classe Employee, portanto, ajuda a corrigir esse tipo de problema em seu aplicativo.

Quando você muda o FirstName para Name novamente, você verá a saída desejada.

Ferramentas de depuração de interface do usuário para XAML

As ferramentas de depuração da IU para XAML são introduzidas com o Visual Studio 2015 para inspecionar o código XAML no tempo de execução. Com a ajuda dessas ferramentas, o código XAML é apresentado na forma de árvore visual de seu aplicativo WPF em execução e também nas diferentes propriedades do elemento de interface do usuário na árvore. Para habilitar essa ferramenta, siga as etapas abaixo.

  • Step 1 - Vá para o menu Ferramentas e selecione Opções no menu Ferramentas.

  • Step 2 - Você verá a seguinte caixa de diálogo.

  • Step 3 - Vá para Opções Gerais no item Depuração no lado esquerdo.

  • Step 4 - Marque a opção destacada, ou seja, “Habilitar ferramentas de depuração da IU para XAML”

  • Step 5 - Pressione o botão OK.

Agora execute qualquer aplicativo XAML ou use o seguinte código XAML -

<Window x:Class = "XAMLTestBinding.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   Title = "MainWindow" Height = "350" Width = "604">
	
   <StackPanel>
      <ComboBox Name = "comboBox" Margin = "50" Width = "100">
         <ComboBoxItem Content = "Green"/>
         <ComboBoxItem Content = "Yellow" IsSelected = "True"/>
         <ComboBoxItem Content = "Orange" />
      </ComboBox>
		
      <TextBox Name = "textBox" Margin = "50" Width = "100" 
         Height = "23" VerticalAlignment = "Top" Text = "{
         Binding ElementName = comboBox, Path = SelectedItem.Content, 
         Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" 
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}"> 
      </TextBox>
   </StackPanel>
	
</Window>

Quando o aplicativo for executado, ele mostrará a Árvore Visual Live onde todos os elementos são mostrados em uma árvore.

Esta Árvore Visual Live mostra a estrutura de layout completa para entender onde os elementos da IU são colocados. Mas essa opção está disponível apenas no Visual Studio 2015. Se você estiver usando uma versão mais antiga do Visual studio, não poderá usar essa ferramenta; entretanto, há outra ferramenta que pode ser integrada ao Visual Studio, como o XAML Spy para Visual Studio. Você pode baixá-lo dehttp://xamlspy.com/download. Recomendamos que você baixe essa ferramenta se estiver usando uma versão mais antiga do Visual Studio.

O XAML tem um dos recursos mais poderosos fornecidos para criar controles personalizados que tornam muito fácil criar controles personalizáveis ​​e ricos em recursos. Controles personalizados são usados quando todo o built-in controles fornecidos pela Microsoft não está cumprindo seus critérios ou você não quer pagar por 3 rd controles do partido.

Neste capítulo, você aprenderá como criar controles personalizados. Antes de começarmos a dar uma olhada nos controles personalizados, vamos primeiro dar uma olhada rápida em um controle do usuário.

Controle do usuário

Os controles de usuário fornecem uma técnica para coletar e combinar diferentes controles integrados e empacotá-los em XAML reutilizável. Os controles do usuário são usados ​​nos seguintes cenários -

  • Se o controle consiste em controles existentes, ou seja, você pode criar um único controle de vários controles já existentes.

  • Se o controle não precisar de suporte para temas. Os controles do usuário não suportam personalizações complexas, modelos de controle e também difíceis de estilizar.

  • Se um desenvolvedor preferir escrever controles usando o modelo code-behind, onde uma visão e um código direto são escritos para manipuladores de eventos.

  • Você não compartilhará seu controle entre os aplicativos.

Vamos dar um exemplo de controle do usuário e seguir as etapas fornecidas abaixo -

  • Step 1 - Crie um novo projeto WPF e, a seguir, clique com o botão direito na sua solução e selecione Adicionar> Novo Item ...

  • Step 2 - A seguinte caixa de diálogo será aberta, agora selecione User Control (WPF) e nomeá-lo MyUserControl.

  • Step 3 - Clique no botão Adicionar e você verá que dois novos arquivos (MyUserControl.xaml e MyUserControl.cs) serão adicionados à sua solução.

A seguir, é fornecido o código XAML no qual um botão e uma caixa de texto são criados com algumas propriedades no arquivo MyUserControl.xaml.

<UserControl x:Class = "XAMLUserControl.MyUserControl" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
   mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300">
	
   <Grid>
      <TextBox Height = "23" HorizontalAlignment = "Left" 
         Margin = "80,49,0,0" Name = "txtBox" VerticalAlignment = "Top" Width = "200" />
      <Button Content = "Click Me" Height = "23" 
         HorizontalAlignment = "Left" Margin = "96,88,0,0" Name = "button" 
         VerticalAlignment = "Top" Width = "75" Click = "button_Click" />
   </Grid>
	
</UserControl>

A seguir está o código C # para o evento de clique de botão no arquivo MyUserControl.cs que atualiza a caixa de texto.

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace XAMLUserControl {
   /// <summary> 
      /// Interaction logic for MyUserControl.xaml
   /// </summary> 
	
   public partial class MyUserControl : UserControl {
      public MyUserControl() {
         InitializeComponent(); 
      }
      private void button_Click(object sender, RoutedEventArgs e) { 
         txtBox.Text = "You have just clicked the button"; 
      } 
   }
}

Aqui está a implementação em MainWindow.xaml para adicionar o controle de usuário.

<Window x:Class = "XAMLUserControl.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:control = "clr-namespace:XAMLUserControl" 
   Title = "MainWindow" Height = "350" Width = "525">
	
   <Grid>
      <control:MyUserControl/>
   </Grid>
	
</Window>

Quando você compila e executa o código acima, ele irá produzir a seguinte saída -

Agora clique no botão "Click Me" e você verá que o texto da caixa de texto é atualizado.

Controles personalizados

Um controle personalizado é uma classe que oferece seu próprio estilo e modelo que são normalmente definidos em generic.xaml. Os controles personalizados são usados ​​nos seguintes cenários,

  • Se o controle não existe e você tem que criá-lo do zero.

  • Se você deseja estender ou adicionar funcionalidade a um controle preexistente, adicionando uma propriedade extra ou uma funcionalidade extra para se adequar ao seu cenário específico.

  • Se seus controles precisam oferecer suporte a temas e estilos.

  • Se você deseja compartilhar o controle entre os aplicativos.

Vamos dar um exemplo de controle personalizado e seguir as etapas fornecidas abaixo.

  • Step 1 - Crie um novo projeto WPF e, a seguir, clique com o botão direito na sua solução e selecione Adicionar> Novo Item ...

  • Step 2- A seguinte caixa de diálogo será aberta. Agora selecioneCustom Control (WPF) e nomeá-lo MyCustomControl.

  • Step 3 - Clique no botão Adicionar e você verá que dois novos arquivos (Themes / Generic.xaml e MyCustomControl.cs) serão adicionados à sua solução.

A seguir está o código XAML no qual o estilo é definido para o controle personalizado no arquivo Generic.xaml.

<ResourceDictionary 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local = "clr-namespace:XAMLCustomControls">
	
   <Style TargetType = "{x:Type local:MyCustomControl}"
      BasedOn = "{StaticResource {x:Type Button}}"> 
      <Setter Property = "Background" Value = "LightSalmon"/>
      <Setter Property = "Foreground" Value = "Blue"/>
   </Style>
	
</ResourceDictionary>

A seguir está o código C # para a classe MyCustomControl que é herdado da classe do botão e no construtor, ele substitui os metadados.

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace XAMLCustomControls {
   public class MyCustomControl : Button {
      static MyCustomControl() {
         DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), 
            new FrameworkPropertyMetadata(typeof(MyCustomControl)));
      }
   }
}

A seguir, é fornecida a implementação do evento de clique de controle personalizado em C #, que atualiza o texto do bloco de texto.

using System; 
using System.Windows; 
using System.Windows.Controls;

namespace XAMLCustomControls {
   /// <summary> 
      /// Interaction logic for MainWindow.xaml 
   /// </summary> 
	
   public partial class MainWindow : Window {
      public MainWindow() { 
         InitializeComponent(); 
      }
      private void customControl_Click(object sender, RoutedEventArgs e) {
         txtBlock.Text = "You have just click your custom control"; 
      } 
   }
}

Aqui está a implementação em MainWindow.xaml para adicionar o controle personalizado e um TextBlock.

<Window x:Class = "XAMLCustomControls.MainWindow" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:control = "clr-namespace:XAMLCustomControls" Title = "MainWindow"
   Height = "350" Width = "604">
	
   <StackPanel>
      <control:MyCustomControl x:Name = "customControl" 
         Content = "Click Me" Width = "70" Margin = "10" Click = "customControl_Click"/>
      <TextBlock Name = "txtBlock" Width = "250" Height = "30"/>
   </StackPanel>
	
</Window>

Quando você compila e executa o código acima, ele produzirá a seguinte saída. Observe que a saída contém um controle personalizado que é um botão personalizado.

Agora clique no botão personalizado. Você verá que o texto do bloco de texto é atualizado.