Controlli

Windows Presentation Foundation (WPF) viene fornito con molti dei componenti comuni dell'interfaccia utente usati in quasi tutte le applicazioni Windows, ad esempio Button, LabelTextBox, Menu, e ListBox. In passato, questi oggetti sono stati indicati come controlli. Mentre WPF SDK continua a usare il termine "control" per indicare in modo libero qualsiasi classe che rappresenta un oggetto visibile in un'applicazione, è importante notare che una classe non deve ereditare dalla Control classe per avere una presenza visibile. Le classi che ereditano dalla classe Control contengono un oggetto ControlTemplate, che consente al consumer di un controllo di modificare radicalmente l'aspetto del controllo stesso senza dover creare una nuova sottoclasse. Questo argomento illustra in che modo i controlli (sia quelli che ereditano dalla classe Control che quelli che non ereditano da tale classe) vengono comunemente usati in WPF.

Creazione dell'istanza di un controllo

Puoi aggiungere un controllo a un'applicazione usando Extensible Application Markup Language (XAML) o il codice. L'esempio seguente illustra come creare una semplice applicazione che chiede all'utente di indicare nome e cognome. Questo esempio crea sei controlli: due etichette, due caselle di testo e due pulsanti, in XAML. È possibile creare tutti i controlli in modo analogo.

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

Nell'esempio seguente viene creata la stessa applicazione nel codice. Per brevità, la creazione di Grid, grid1, è stata esclusa dall'esempio. grid1 presenta le stesse definizioni di colonna e riga illustrate nell'esempio XAML precedente.

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

Modifica dell'aspetto di un controllo

È spesso necessario modificare l'aspetto di un controllo per adattarlo all'aspetto dell'applicazione. Per modificare l'aspetto di un controllo, è possibile adottare una delle procedure seguenti, a seconda del risultato che si intende ottenere:

  • Modificare il valore di una proprietà del controllo.

  • Creare un oggetto Style per il controllo.

  • Creare un nuovo oggetto ControlTemplate per il controllo.

Modifica di un valore della proprietà del controllo

Esistono proprietà che consentono di modificare l'aspetto del controllo, ad esempio la proprietà Background di un controllo Button. È possibile impostare il valore delle proprietà sia in XAML che nel codice. Nell'esempio seguente vengono impostate le proprietà Background, FontSize e FontWeight di un controllo Button in 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>

Nell'esempio seguente vengono impostate le stesse proprietà nel codice.

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

Creazione di uno stile per un controllo

WPF consente di specificare l'aspetto dei controlli a livello globale, invece impostare le proprietà per ogni istanza dell'applicazione, creando un oggetto Style. Nell'esempio seguente viene creato un oggetto Style che viene applicato a ogni controllo Button nell'applicazione. Le definizioni Style vengono in genere specificate in XAML in un oggetto ResourceDictionary, ad esempio la proprietà Resources dell'oggetto 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>

È anche possibile applicare uno stile solo a determinati controlli di un tipo specifico assegnando una chiave allo stile e specificando tale chiave nella proprietà Style del controllo. Per altre informazioni sugli stili, vedere Applicazione di stili e modelli.

Creazione di un ControlTemplate

Un oggetto Style consente di impostare le proprietà per più controlli contemporaneamente, ma a volte può essere necessario personalizzare l'aspetto di Control più di quanto sia possibile ottenere creando un oggetto Style. Le classi che ereditano dalla classe Control dispongono di un oggetto ControlTemplate, che definisce la struttura e l'aspetto di un oggetto Control. La proprietà Template di un elemento Control è pubblica, pertanto è possibile assegnare a un elemento Control un controllo ControlTemplate diverso da quello predefinito. Spesso è possibile specificare un nuovo oggetto ControlTemplate per Control invece di ereditare da un controllo per personalizzare l'aspetto di Control.

Si consideri un controllo molto comune, ad esempio Button. Il comportamento principale di Button consiste nel consentire a un'applicazione di eseguire qualche azione quando l'utente fa clic su di esso. Per impostazione predefinita, l'oggetto Button in WPF viene visualizzato come un rettangolo in rilievo. Quando si sviluppa un'applicazione, è possibile usufruire del comportamento di Button, ovvero gestendo l'evento click del pulsante, ma è possibile modificare l'aspetto del pulsante più di quanto si possa fare modificando le proprietà del pulsante stesso. In questo caso, è possibile creare un nuovo controllo ControlTemplate.

Nell'esempio seguente viene creato un elemento ControlTemplate per un controllo Button. L'elemento ControlTemplate crea un controllo Button con angoli arrotondati e uno sfondo sfumato. L'elemento ControlTemplate contiene un controllo Border la cui proprietà Background è LinearGradientBrush con due oggetti GradientStop. Il primo oggetto GradientStop usa l'associazione dati per associare la proprietà Color di GradientStop al colore dello sfondo del pulsante. Quando si imposta la proprietà Background del controllo Button, il colore di tale valore verrà usato come primo GradientStop. Per altre informazioni sul data binding, vedere Cenni preliminari sull'associazione dati. Nell'esempio viene inoltre creato un oggetto Trigger che modifica l'aspetto del controllo 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>

Nota

Affinché l'esempio funzioni correttamente, la proprietà Background del controllo Button deve essere impostata su SolidColorBrush.

Sottoscrizione di eventi

È possibile sottoscrivere un evento del controllo usando XAML o il codice, ma si può solo gestire un evento nel codice. Nell'esempio seguente viene illustrato come sottoscrivere l'evento Click di un controllo 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

Nell'esempio seguente viene gestito l'evento Click di un controllo 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

Contenuto avanzato dei controlli

La maggior parte delle classi che eredita dalla classe Control può contenere contenuto formattato. Ad esempio, un oggetto Label può contenere qualsiasi oggetto, ad esempio una stringa, un controllo Image o un controllo Panel. Le classi seguenti supportano contenuto avanzato e fungono da classi di base per la maggior parte dei controlli in WPF.

Per altre informazioni su queste classi di base, vedere Modello di contenuto WPF.

Vedi anche