Steuerelemente

Windows Presentation Foundation (WPF) beinhaltet viele gängige Benutzeroberflächenkomponenten, die in nahezu jeder Windows-Anwendung zum Einsatz kommen, beispielsweise Button, Label, TextBox, Menu und ListBox. In der Vergangenheit wurden diese Objekte als Steuerelemente bezeichnet. Während im WPF-SDK weiterhin der Begriff „Control“ (Steuerelement) für jede Klasse verwendet wird, die ein sichtbares Objekt in einer Anwendung repräsentiert, ist es wichtig zu beachten, dass eine Klasse nicht notwendigerweise von der Control-Klasse erben muss, um eine sichtbare Präsenz zu haben. Klassen, die von der Control-Klasse erben, enthalten ein ControlTemplate-Objekt, das es dem Benutzer eines Steuerelements ermöglicht, die Darstellung des Steuerelements radikal zu ändern, ohne eine neue Unterklasse erstellen zu müssen. In diesem Thema wird erläutert, wie Steuerelemente (sowohl die, die von der Control-Klasse erben, als auch die, die nicht von ihr erben) gewöhnlich in WPF verwendet werden.

Erstellen einer Instanz eines Steuerelements

Sie können einer Anwendung ein Steuerelement hinzufügen, indem Sie XAML (Extensible Application Markup Language) oder Code verwenden. Im folgenden Beispiel wird veranschaulicht, wie Sie eine einfache Anwendung erstellen, die Vor- und Nachname eines Benutzers abfragt. In diesem Beispiel werden sechs Steuerelemente in XAML erstellt: zwei Bezeichnungen, zwei Textfelder und zwei Schaltflächen. Alle Steuerelemente können auf ähnliche Weise erstellt werden.

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

Im folgenden Beispiel wird die gleiche Anwendung in Code erstellt. Aus Gründen der Übersichtlichkeit wurde die Erstellung von Grid, grid1, aus dem Beispiel ausgeschlossen. grid1 verfügt über die gleichen Spalten- und Zeilendefinitionen wie im vorangehenden XAML-Beispiel.

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

Ändern der Darstellung eines Steuerelements

Es ist üblich, die Darstellung eines Steuerelements zu ändern, sodass es zum Aussehen und Verhalten der Anwendung passt. Sie können die Darstellung eines Steuerelements je nach Absicht auf eine der folgenden Weisen ändern:

  • Ändern des Werts einer Eigenschaft des Steuerelements.

  • Erstellen Sie eine Style-Klasse für das Steuerelement.

  • Erstellen Sie eine neue ControlTemplate für das Steuerelement.

Ändern eines Eigenschaftswerts eines Steuerelements

Viele Steuerelemente haben Eigenschaften, mit denen Sie die Darstellung des Steuerelements verändern können, z. B. den Background eines Button-Objekts. Sie können die Werteigenschaften sowohl in XAML als auch in Code festlegen. Im folgenden Beispiel werden die Eigenschaften Background, FontSize und FontWeight für ein Button-Objekt in XAML festgelegt.

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

Im folgenden Beispiel werden die gleichen Eigenschaften in Code festgelegt.

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

Erstellen eines Stils für ein Steuerelement

WPF ermöglicht Ihnen, die Darstellung von Steuerelementen global zu bestimmen, anstatt die Eigenschaften auf jeder Instanz in der Anwendung durch Erstellen eines Style-Objekts festzulegen. Im folgenden Beispiel wird eine Style-Klasse erstellt, die auf jedes Button-Objekt in der Anwendung angewendet wird. Style-Definitionen werden in der Regel in XAML in einem ResourceDictionary definiert, wie z. B. die Eigenschaft Resources für das 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>

Sie können einen Stil auch nur auf einige Steuerelemente eines bestimmten Typs anwenden, indem Sie dem Stil einen Schlüssel zuweisen und diesen Schlüssel in der Style-Eigenschaft des Steuerelements angeben. Weitere Informationen zu Stilen finden Sie unter Erstellen von Formaten und Vorlagen.

Erstellen einer Steuerelementvorlage

Mit einer Style-Klasse können Sie Eigenschaften für mehrere Steuerelemente gleichzeitig festlegen. Es kann jedoch vorkommen, dass Sie die Darstellung eines Control-Steuerelements noch weiter ändern möchten, als Ihnen das Erstellen einer Style-Klasse erlaubt. Klassen, die von der Control-Klasse erben, verfügen über eine ControlTemplate, in der die Struktur und die Darstellung eines Control-Objekts definiert sind. Die Template-Eigenschaft eines Control-Objekts ist öffentlich, sodass Sie für ein Control-Objekt eine ControlTemplate festlegen können, die von der Standardeinstellung abweicht. Oft können Sie für ein Control-Objekt eine neue ControlTemplate angeben, statt sie von einem Steuerelement zu übernehmen, um die Darstellung eines Control-Objekts anzupassen.

Sehen Sie sich das sehr häufig verwendete Steuerelement Button an. Der Hauptzweck eines Button-Objekts besteht darin, einer Anwendung die Durchführung einer Aktion zu ermöglichen, wenn der Benutzer darauf klickt. In der Standardeinstellung wird das Button-Objekt in WPF als ein erhöhtes Rechteck angezeigt. Beim Entwickeln einer Anwendung können Sie das Verhalten eines Button-Steuerelements nutzen, d. h. das Klickereignis der Schaltfläche verarbeiten. Zudem haben Sie jedoch die Möglichkeit, die Darstellung der Schaltfläche weitergehend zu verändern, als dies durch Ändern der Schaltflächeneigenschaften möglich ist. In diesem Fall können Sie eine neue ControlTemplate erstellen.

Im folgenden Beispiel wird eine ControlTemplate für ein Button-Objekt erstellt. Die ControlTemplate erstellt ein Button-Objekt mit abgerundeten Ecken und einem Hintergrund mit Farbverlauf. Die ControlTemplate enthält ein Border-Objekt, dessen Background aus einem LinearGradientBrush mit zwei GradientStop-Objekten besteht. Das erste GradientStop-Objekt verwendet die Datenbindung, um die Color-Eigenschaft des GradientStop-Objekts an die Farbe des Schaltflächenhintergrunds zu binden. Wenn Sie die Background-Eigenschaft des Button-Objekts festlegen, wird die Farbe dieses Werts als erstes GradientStop-Objekt verwendet. Weitere Informationen zu Datenbindungen finden Sie unter Übersicht über Datenbindung. Im Beispiel wird außerdem ein Trigger erstellt, der die Darstellung des Button-Objekts ändert, wenn IsPressed den Wert true aufweist.

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

Hinweis

Die Background-Eigenschaft des Button-Objekts muss auf SolidColorBrush festgelegt werden, damit dieses Beispiel ordnungsgemäß funktioniert.

Abonnieren von Ereignissen

Sie können das Ereignis eines Steuerelements abonnieren, indem Sie entweder XAML oder Code verwenden, aber Sie können ein Ereignis nur in Code behandeln. Im folgenden Beispiel wird das Abonnieren des Click-Ereignisses für ein Button-Objekt veranschaulicht.

<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

Im folgenden Beispiel wird das Click-Ereignis eines Button-Objekts verarbeitet.

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

Umfangreicher Inhalt in Steuerelementen

Die meisten Klassen, die von der Control-Klasse erben, besitzen die Kapazität für umfangreiche Inhalte. Beispielsweise kann ein Label-Objekt jedes Objekt enthalten, z. B. eine Zeichenfolge, ein Image oder ein Panel. Die folgenden Klassen unterstützen umfangreichen Inhalt und dienen als Basisklassen für die meisten Steuerelemente in WPF.

Weitere Informationen zu diesen Basisklassen finden Sie unter WPF-Inhaltsmodell.

Weitere Informationen