Элементы управления

Windows Presentation Foundation (WPF) поставляется с большинством общих компонентов пользовательского интерфейса, которые используются практически в каждом приложении Windows, например Button, Label, TextBox, Menu и ListBox. Ранее эти объекты назывались элементами управления. Хотя пакет SDK WPF продолжает использовать термин "элемент управления" для общего обозначения любого класса, который представляет видимый объект в приложении, обратите внимание, что классу не требуется наследование от класса Control, чтобы иметь визуальное представление. Классы, которые наследуют от класса Control, содержат ControlTemplate, который позволяет потребителю элемента управления радикально изменить внешний вид элемента управления, для чего не требуется создавать новый подкласс. В этом разделе обсуждается использование элементов управления в WPF (тех, которые наследуются от класса Control, и тех, которые не наследуются).

В этом разделе содержатся следующие подразделы.

  • Создание экземпляра элемента управления
  • Изменение внешнего вида элемента управления
  • Подписка на события
  • Расширенное содержимое в элементах управления
  • Связанные разделы

Создание экземпляра элемента управления

Чтобы добавить элемент управления в приложение, используйте Extensible Application Markup Language (XAML) или код. Следующий пример показывает, как создать простое приложение, которое запрашивает у пользователя его имя и фамилию. Этом примере создает в XAML шесть элементов управления: две подписи, два текстовых поля и две кнопки. Все элементы управления могут быть созданы аналогичным образом.

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

В следующем примере то же самое приложение создается в коде. Создание Grid, grid1 для краткости было исключено из примера. В grid1 указаны определения столбца и строки, приведенные в предыдущем примере XAML.

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

}

Изменение внешнего вида элемента управления

Изменение внешнего вида элемента управления для подбора внешнего вида приложения — это частая задача. Чтобы изменить внешний вид элемента управления, выполните одно из следующих действий в зависимости от того, что требуется выполнить:

  • Изменить значение свойства элемента управления.

  • Создайте Style для элемента управления.

  • Создайте новый ControlTemplate для элемента управления.

Изменение значения свойства элемента управления

Многие элементы управления обладают свойствами, которые позволяют изменять внешний вид элемента управления, например Background Button. Можно задать свойства значения в коде и в XAML. В следующем примере свойства Background, FontSize, и FontWeight на Button устанавливаются в 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>

В следующем примере те же свойства задаются в коде.

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;

Создание стиля для элемента управления

WPF предоставляет возможность задавать внешний вид для нескольких элементов управления вместо того, чтобы задавать свойства для каждого экземпляра в приложении. Это достигается путем создания Style. В следующем примере создается Style, который применяется к каждому Button в приложении. Определения Style обычно указываются в XAML в ResourceDictionary, например свойство Resources объекта 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>

Стиль можно также применить только к определенным элементам управления определенного типа путем присвоения ключа для стиля и задания этого ключа в свойстве элемента управления Style. За дополнительными сведениями о стилях обратитесь к разделу Стилизация и использование шаблонов.

Создание ControlTemplate

Style позволяет задать свойства для нескольких элементов управления одновременно. Однако в некоторых случаях может потребоваться изменить внешний вид Control сверх того, что достигается путем создания Style. Классы, которые наследуют от класса Control, имеют ControlTemplate, который определяет структуру и внешний вид Control. Свойство Template Control является открытым, поэтому пользователь может предоставить Control ControlTemplate, который отличен от задаваемого по умолчанию. Часто можно указать новый ControlTemplate для Control вместо наследования элемента управления для настройки внешнего вида Control.

Рассмотрим очень часто используемый элемент, Button. Основное поведение Button заключается в том, чтобы позволить приложению выполнить некоторое действие, когда пользователь щелкает этот элемент. По умолчанию Button в WPF отображается как приподнятый прямоугольник. При разработке приложения может понадобиться поведение Button (т.е. обработка события нажатия кнопки), однако при этом внешний вид кнопки может быть изменен так, что изменения свойств кнопки будет недостаточно. В этом случае можно создать новый ControlTemplate.

В следующем примере создается ControlTemplate для Button. ControlTemplate создает Button с округленными углами и градиентным фоном. ControlTemplate содержит Border, чей Background является LinearGradientBrush с двумя объектами GradientStop. Первый GradientStop использует привязку данных для привязки свойства Color GradientStop к цвету фона кнопки. При установке свойства Background из Button цвет этого значения будет использоваться как первый GradientStop. Дополнительные сведения о привязке данных см. в разделе Общие сведения о связывании данных. В примере также создается Trigger, который изменяет внешний вид Button, когда 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>
ПримечаниеПримечание

Для правильной работы примера свойству Background из Button должно быть присвоено SolidColorBrush.

Подписка на события

Подписаться на событие элемента управления можно с помощью XAML или кода, но обрабатывать событие возможно только в коде. В следующем примере показано, как подписаться на событие Click из 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);

В следующем примере обрабатывается событие Click из 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);
}

Расширенное содержимое в элементах управления

Большинство классов, которые наследуются от класса Control, имеют возможность хранения расширенного содержимого. Например, Label может содержать любой объект, такой как строка, Image, или Panel. Следующие классы обеспечивают поддержку для расширенного содержимого и служат базовым классами для большинства элементов управления в WPF.

Дополнительные сведения об этих базовых классах см. в разделе Модель содержимого WPF.

См. также

Задачи

Практическое руководство. Включение команды

Ссылки

Категории элементов управления

Основные понятия

Стилизация и использование шаблонов

Общие сведения о шаблонах данных

Общие сведения о связывании данных

Другие ресурсы

Библиотека элементов управления

Входные данные и команды

Пошаговые руководства: создание пользовательской анимированной кнопки

Настройка элементов управления