Controles

Windows Presentation Foundation (WPF) se distribuye con muchos de los componentes de interfaz de usuario comunes que se utilizan en casi todas las aplicaciones Windows, como Button, Label, TextBox, Menu y ListBox. Históricamente, estos objetos se denominan controles. Aunque en el SDK de WPF se continúa usando el término "control" para denominar genéricamente cualquier clase que representa un objeto visible de una aplicación, es importante tener en cuenta que una clase no necesita heredar de la clase Control para tener una presencia visible. Las clases que heredan de la clase Control contienen una ControlTemplate, que permite al consumidor de un control cambiar radicalmente el aspecto de éste sin tener que crear una nueva subclase. En este tema se describen los usos más comunes de los controles (tanto los que heredan de la clase Control como los que no) en WPF.

Este tema contiene las secciones siguientes.

  • Crear una instancia de un control
  • Cambiar el aspecto de un control
  • Suscribirse a eventos
  • Contenido enriquecido en los controles
  • Temas relacionados

Crear una instancia de un control

Puede agregar un control a una aplicación mediante Extensible Application Markup Language (XAML) o código. En el ejemplo siguiente se muestra cómo crear una aplicación simple que pide al usuario su nombre y su apellido. En este ejemplo se crean seis controles: dos etiquetas, dos cuadros de texto y dos botones, en XAML. Todos los controles se pueden crear de igual 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>

En el ejemplo siguiente se crea la misma aplicación mediante código. Para mayor brevedad, la creación de Grid, grid1 se ha excluido del ejemplo. grid1 tiene las mismas definiciones de columnas y filas que en el ejemplo de XAML anterior.

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 'CreateControls
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);

}

Cambiar el aspecto de un control

Es común cambiar el aspecto de un control para ajustarlo a la apariencia y funcionamiento de la aplicación. Puede cambiar el aspecto de un control realizando una de las acciones siguientes, dependiendo de lo que desea lograr:

  • Cambiar el valor de una propiedad del control.

  • Crear un Style para el control.

  • Crear una nueva ControlTemplate para el control.

Cambiar el valor de una propiedad de un control

Muchos controles tienen propiedades que permiten cambiar el aspecto del control, como el fondo (Background) de un botón (Button). Puede establecer las propiedades de valor en XAML y mediante código. En el ejemplo siguiente se establecen las propiedades Background, FontSize y FontWeight de un Button en 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>

En el ejemplo siguiente se establecen las mismas propiedades mediante código.

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
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;

Crear un estilo para un control

WPF permite especificar el aspecto de los controles de manera global, en lugar de establecer las propiedades en cada instancia de la aplicación, si se crea una clase Style. En el ejemplo siguiente se crea una clase Style que se aplica a cada control Button en la aplicación. Las definiciones de Style se suelen definir en XAML en una clase ResourceDictionary, como la propiedad Resources de la clase 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>

También puede aplicar un estilo únicamente a determinados controles de un tipo específico asignando una clave al estilo y especificando esa la clave en la propiedad Style del control. Para obtener más información acerca de los estilos, consulte Aplicar estilos y plantillas.

Crear una plantilla de control

Style permite establecer las propiedades en varios controles a la vez, pero en ocasiones puede ser conveniente personalizar el aspecto de un Control más allá de lo que se puede hacer creando un Style. Las clases que heredan de la clase Control tienen una ControlTemplate, que define la estructura y el aspecto de un Control. La propiedad Template de Control es pública, por lo que puede dar una ControlTemplate a un Control diferente de la predeterminada. Con frecuencia, se puede especificar una ControlTemplate nueva para un Control en lugar de heredar de un control para personalizar el aspecto de Control.

Tomemos uno de los controles comunes, Button. El comportamiento primario de Button es permitir que una aplicación realice una acción cuando el usuario hace clic en él. De manera predeterminada, el control Button aparece en WPF como un rectángulo elevado. Al programar una aplicación, puede que quiera aprovechar el comportamiento de Button, es decir, controlar el evento de hacer clic en el botón, pero que desee cambiar el aspecto del botón más allá de lo que es posible cambiando las propiedades del mismo. En este caso, puede crear una nueva ControlTemplate.

En el ejemplo siguiente se crea un objeto ControlTemplate para un control Button. ControlTemplate crea Button con esquinas redondeadas y fondo degradado. ControlTemplate contiene un Border cuyo Background es LinearGradientBrush con dos objetos GradientStop. El primer GradientStop utiliza el enlace de datos para enlazar la propiedad Color de GradientStop al color de fondo del botón. Al establecer la propiedad Background de Button, el color de ese valor se utilizará como primer GradientStop. Para obtener más información sobre el enlace de datos, vea Información general sobre el enlace de datos. En el ejemplo también se crea un Trigger que cambia el aspecto de Button cuando IsPressed es 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>
NotaNota

La propiedad Background de Button debe estar establecida en SolidColorBrush para que ejemplo funcione correctamente.

Suscribirse a eventos

Puede suscribirse a un evento de un control mediante XAML o código, pero los eventos únicamente se pueden controlar mediante código. En el ejemplo siguiente se muestra cómo suscribirse al evento Click de un Button.

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

En el ejemplo siguiente se controla el evento Click de un control Button.

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

End Sub 'submit_Click
void submit_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Hello, " + firstName.Text + " " + lastName.Text);
}

Contenido enriquecido en los controles

La mayoría de las clases que heredan de la clase Control tienen la capacidad de incluir contenido enriquecido. Por ejemplo, un control Label puede contener cualquier objeto, como una cadena, una Imageo un Panel. Las clases siguientes proporcionan compatibilidad con el contenido enriquecido y actúan como clases base para la mayoría de los controles en WPF.

Para obtener más información sobre estas clases base, vea Modelo de contenido de WPF.

Vea también

Tareas

Cómo: Habilitar un comando

Referencia

Agrupar controles por categoría

Conceptos

Aplicar estilos y plantillas

Información general sobre plantillas de datos

Información general sobre el enlace de datos

Otros recursos

Biblioteca de controles

Acciones del usuario y comandos

Tutoriales: Crear un botón animado personalizado

Personalización de controles