Controles

O Windows Presentation Foundation (WPF) é fornecido com muitos dos componentes comuns da interface do usuário que são usados em quase todos os aplicativos do Windows, como Button, , , MenuLabelTextBoxe .ListBox Historicamente, esses objetos são chamados de controles. Embora o WPF SDK continue a usar o termo "controle" para significar vagamente qualquer classe que represente um objeto visível em um aplicativo, é importante observar que uma classe não precisa herdar da Control classe para ter uma presença visível. Classes que herdam da classe Control contêm um ControlTemplate, que permite ao consumidor de um controle alterar radicalmente a aparência do controle sem precisar criar uma nova subclasse. Este tópico discute como os controles (tanto aqueles que herdam da classe Control quanto aqueles que não o fazem) são normalmente usados no WPF.

Criando uma instância de um controle

Você pode adicionar um controle a um aplicativo usando XAML (Extensible Application Markup Language) ou código. O exemplo a seguir mostra como criar um aplicativo simples que solicita a um usuário o nome e sobrenome. Este exemplo cria seis controles: dois rótulos, duas caixas de texto e dois botões, em XAML. Todos os controles podem ser criados da mesma forma.

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="30"/>
    <RowDefinition Height="30"/>
    <RowDefinition Height="30"/>
    <RowDefinition/>
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
    <ColumnDefinition/>
    <ColumnDefinition/>
  </Grid.ColumnDefinitions>

  <Label>
    Enter your first name:
  </Label>
  <TextBox Grid.Row="0" Grid.Column="1" 
           Name="firstName" Margin="0,5,10,5"/>

  <Label Grid.Row="1" >
    Enter your last name:
  </Label>
  <TextBox Grid.Row="1" Grid.Column="1" 
           Name="lastName" Margin="0,5,10,5"/>

  <Button Grid.Row="2" Grid.Column="0" 
          Name="submit" Margin="2">
    View message
  </Button>

  <Button Grid.Row="2" Grid.Column="1" 
          Name="Clear" Margin="2">
    Clear Name
  </Button>
</Grid>

O exemplo a seguir cria o mesmo aplicativo no código. Para fins de brevidade, a criação do Grid, grid1, foi excluída da amostra. grid1 tem as mesmas definições de coluna e linha, conforme mostrado no exemplo XAML anterior.

Label firstNameLabel;
Label lastNameLabel;
TextBox firstName;
TextBox lastName;
Button submit;
Button clear;

void CreateControls()
{
    firstNameLabel = new Label();
    firstNameLabel.Content = "Enter your first name:";
    grid1.Children.Add(firstNameLabel);

    firstName = new TextBox();
    firstName.Margin = new Thickness(0, 5, 10, 5);
    Grid.SetColumn(firstName, 1);
    grid1.Children.Add(firstName);

    lastNameLabel = new Label();
    lastNameLabel.Content = "Enter your last name:";
    Grid.SetRow(lastNameLabel, 1);
    grid1.Children.Add(lastNameLabel);

    lastName = new TextBox();
    lastName.Margin = new Thickness(0, 5, 10, 5);
    Grid.SetColumn(lastName, 1);
    Grid.SetRow(lastName, 1);
    grid1.Children.Add(lastName);

    submit = new Button();
    submit.Content = "View message";
    Grid.SetRow(submit, 2);
    grid1.Children.Add(submit);

    clear = new Button();
    clear.Content = "Clear Name";
    Grid.SetRow(clear, 2);
    Grid.SetColumn(clear, 1);
    grid1.Children.Add(clear);
}
Private firstNameLabel As Label
Private lastNameLabel As Label
Private firstName As TextBox
Private lastName As TextBox
Private submit As Button
Private clear As Button

Sub CreateControls()
    firstNameLabel = New Label()
    firstNameLabel.Content = "Enter your first name:"
    grid1.Children.Add(firstNameLabel)

    firstName = New TextBox()
    firstName.Margin = New Thickness(0, 5, 10, 5)
    Grid.SetColumn(firstName, 1)
    grid1.Children.Add(firstName)

    lastNameLabel = New Label()
    lastNameLabel.Content = "Enter your last name:"
    Grid.SetRow(lastNameLabel, 1)
    grid1.Children.Add(lastNameLabel)

    lastName = New TextBox()
    lastName.Margin = New Thickness(0, 5, 10, 5)
    Grid.SetColumn(lastName, 1)
    Grid.SetRow(lastName, 1)
    grid1.Children.Add(lastName)

    submit = New Button()
    submit.Content = "View message"
    Grid.SetRow(submit, 2)
    grid1.Children.Add(submit)

    clear = New Button()
    clear.Content = "Clear Name"
    Grid.SetRow(clear, 2)
    Grid.SetColumn(clear, 1)
    grid1.Children.Add(clear)


End Sub

Alterando a aparência de um controle

É comum alterar a aparência de um controle para ajustar a aparência do seu aplicativo. Você pode alterar a aparência de um controle seguindo um destes procedimentos, dependendo do que deseja realizar:

  • Altere o valor de uma propriedade do controle.

  • Crie um Style para o controle.

  • Crie um novo ControlTemplate para o controle.

Alterando o valor da propriedade do controle

Muitos controles têm propriedades que permitem alterar a forma como o controle aparece, como o Background de um Button. Você pode definir as propriedades de valor em XAML e código. O exemplo a seguir define as propriedades Background, FontSize e FontWeight em um Button em XAML.

<Button FontSize="14" FontWeight="Bold">
  <!--Set the Background property of the Button to
    a LinearGradientBrush.-->
  <Button.Background>
    <LinearGradientBrush StartPoint="0,0.5" 
                            EndPoint="1,0.5">
      <GradientStop Color="Green" Offset="0.0" />
      <GradientStop Color="White" Offset="0.9" />
    </LinearGradientBrush>

  </Button.Background>
  View message
</Button>

O exemplo a seguir define as mesmas propriedades no código.

LinearGradientBrush buttonBrush = new LinearGradientBrush();
buttonBrush.StartPoint = new Point(0, 0.5);
buttonBrush.EndPoint = new Point(1, 0.5);
buttonBrush.GradientStops.Add(new GradientStop(Colors.Green, 0));
buttonBrush.GradientStops.Add(new GradientStop(Colors.White, 0.9));

submit.Background = buttonBrush;
submit.FontSize = 14;
submit.FontWeight = FontWeights.Bold;
Dim buttonBrush As New LinearGradientBrush()
buttonBrush.StartPoint = New Point(0, 0.5)
buttonBrush.EndPoint = New Point(1, 0.5)
buttonBrush.GradientStops.Add(New GradientStop(Colors.Green, 0))
buttonBrush.GradientStops.Add(New GradientStop(Colors.White, 0.9))

submit.Background = buttonBrush
submit.FontSize = 14
submit.FontWeight = FontWeights.Bold

Criando um estilo para um controle

O WPF oferece a capacidade de especificar a aparência dos controles por atacado, em vez de definir propriedades em cada instância no aplicativo, criando um Style. O exemplo a seguir cria um Style aplicado a cada Button no aplicativo. Style definições normalmente são definidas em XAML em um ResourceDictionary, como a propriedade Resources do FrameworkElement.

<Style TargetType="Button">
  <Setter Property="FontSize" Value="14"/>
  <Setter Property="FontWeight" Value="Bold"/>
  <Setter Property="Background">
    <Setter.Value>
      <LinearGradientBrush StartPoint="0,0.5" 
                              EndPoint="1,0.5">
        <GradientStop Color="Green" Offset="0.0" />
        <GradientStop Color="White" Offset="0.9" />
      </LinearGradientBrush>

    </Setter.Value>
  </Setter>
</Style>

Você também pode aplicar um estilo a apenas determinados controles de um tipo específico atribuindo uma chave ao estilo e especificando essa chave na propriedade Style de seu controle. Para obter mais informações sobre estilos, confira Estilo e Modelagem.

Criando um ControlTemplate

Um Style permite que você defina propriedades em vários controles de cada vez, mas às vezes você pode querer personalizar a aparência de um Control além do que você pode fazer criando um Style. Classes que herdam da classe Control têm um ControlTemplate, que define a estrutura e a aparência de um Control. A propriedade Template de um Control é pública, para que você possa dar a Control um ControlTemplate diferente do padrão. Geralmente, você pode especificar um novo ControlTemplate para um Control em vez de herdar de um controle para personalizar a aparência de um Control.

Considere o controle muito comum, Button. O comportamento principal de um Button é permitir que um aplicativo execute alguma ação quando o usuário clicar nele. Por padrão, o Button no WPF aparece como um retângulo gerado. Ao desenvolver um aplicativo, talvez você queira aproveitar o comportamento de um Button – ou seja, manipulando o evento de clique do botão – mas pode alterar a aparência do botão além do que você pode fazer alterando as propriedades do botão. Nesse caso, você pode criar um ControlTemplate.

O exemplo a seguir cria um ControlTemplate para um Button. O ControlTemplate cria uma Button com cantos arredondados e uma tela de fundo de gradiente. O ControlTemplate contém um Border cuja Background é uma LinearGradientBrush com dois objetos GradientStop. O primeiro GradientStop usa a associação de dados para associar a propriedade Color do GradientStop à cor da tela de fundo do botão. Quando você definir a propriedade Background do Button, a cor desse valor será usada como o primeiro GradientStop. Para mais informações sobre associação de dados, consulte Visão geral da associação de dados. O exemplo também cria um Trigger que altera a aparência do Button quando IsPressed é true.

<!--Define a template that creates a gradient-colored button.-->
<Style TargetType="Button">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Button">
        <Border 
          x:Name="Border"  
          CornerRadius="20" 
          BorderThickness="1"
          BorderBrush="Black">
          <Border.Background>
            <LinearGradientBrush StartPoint="0,0.5" 
                                 EndPoint="1,0.5">
              <GradientStop Color="{Binding Background.Color, 
                    RelativeSource={RelativeSource TemplatedParent}}" 
                            Offset="0.0" />
              <GradientStop Color="White" Offset="0.9" />
            </LinearGradientBrush>
          </Border.Background>
          <ContentPresenter 
            Margin="2"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            RecognizesAccessKey="True"/>
        </Border>
        <ControlTemplate.Triggers>
          <!--Change the appearance of
          the button when the user clicks it.-->
          <Trigger Property="IsPressed" Value="true">
            <Setter TargetName="Border" Property="Background">
              <Setter.Value>
                <LinearGradientBrush StartPoint="0,0.5" 
                                     EndPoint="1,0.5">
                  <GradientStop Color="{Binding Background.Color, 
                    RelativeSource={RelativeSource TemplatedParent}}" 
                                Offset="0.0" />
                  <GradientStop Color="DarkSlateGray" Offset="0.9" />
                </LinearGradientBrush>
              </Setter.Value>
            </Setter>
          </Trigger>

        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>
<Button Grid.Row="2" Grid.ColumnSpan="2" Name="submitName"
        Background="Green">View message</Button>

Observação

A propriedade Background do Button deve ser definida como um SolidColorBrush para que o exemplo funcione corretamente.

Assinando eventos

Você pode assinar um evento de controle usando XAML ou código, mas só pode manipular um evento no código. O exemplo a seguir mostra como assinar o evento Click de um Button.

<Button Grid.Row="2" Grid.ColumnSpan="2" Name="submitName" Click="submit_Click"
  Background="Green">View message</Button>
submit.Click += new RoutedEventHandler(submit_Click);
AddHandler submit.Click, AddressOf submit_Click

O exemplo a seguir manipula o evento Click de um Button.

void submit_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Hello, " + firstName.Text + " " + lastName.Text);
}
Private Sub submit_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    MessageBox.Show("Hello, " + firstName.Text + " " + lastName.Text)

End Sub

Conteúdo avançado em controles

A maioria das classes que herdam da classe Control tem a capacidade de conter conteúdo avançado. Por exemplo, um Label pode conter qualquer objeto, como uma cadeia de caracteres, um Image ou um Panel. As classes a seguir oferecem suporte para conteúdo avançado e atuam como classes base para a maioria dos controles no WPF.

Para obter mais informações sobre essas classes base, confira o Modelo de Conteúdo do WPF.

Confira também