コントロール

Windows Presentation Foundation (WPF) には、ButtonLabelTextBoxMenuListBox など、ほとんどの Windows アプリケーションで使用される共通の UI コンポーネントが多数付属しています。 これまで、これらのオブジェクトはコントロールと呼ばれてきました。 WPF SDK では、アプリケーションで表示可能なオブジェクトを表すクラスに、広義で "コントロール" という用語が使用され続けていますが、クラスは、表示可能な部分を持つために Control クラスを継承する必要がないことに注意してください。 Control クラスを継承するクラスには、ControlTemplate が含まれます。これを使用すると、コントロールのコンシューマーは、新しいサブクラスを作成しなくても、コントロールの外観を大幅に変更できます。 このトピックでは、WPF でのコントロール (Control クラスを継承するものとそうでないものの両方) の一般的な使用方法について説明します。

コントロールのインスタンスの作成

Extensible Application Markup Language (XAML) またはコードのいずれかを使用して、アプリケーションにコントロールを追加できます。 次の例では、ユーザーに姓と名の入力を求める単純なアプリケーションの作成方法を示します。 この例では、ラベル 2 個、テキスト ボックス 2 個、ボタン 2 個の合計 6 個のコントロールを 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 の例で示したのと同じ列と行が定義されています。

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

コントロールの外観の変更

通常は、アプリケーションの外観に合わせてコントロールの外観を変更します。 コントロールの外観を変更するには、目的に応じて、次のいずれかの手順を実行します。

  • コントロールのプロパティ値を変更します。

  • コントロールに Style を作成します。

  • コントロールに新しい ControlTemplate を作成します。

コントロールのプロパティ値の変更

多くのコントロールには、ButtonBackground など、コントロールの外観を変更するプロパティがあります。 値プロパティは、XAML とコードの両方で設定できます。 次の例では、XAML で、ButtonBackgroundFontSizeFontWeight の各プロパティを設定しています。

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

次の例では、同じプロパティをコードで設定しています。

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

コントロールのスタイル作成

WPF には、アプリケーションの各インスタンスのさまざまなプロパティを設定する代わりに、Style を作成して、コントロールの外観を多数指定する機能があります。 次の例では、アプリケーションの各 Button に適用される Style が作成されます。 Style の定義は、通常、ResourceDictionary では XAML に定義されます (FrameworkElementResources プロパティなど)。

<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 を使用すると、複数のコントロールのプロパティを一度に設定できますが、Style の作成だけでできる以上に、Control の外観をカスタマイズしたい場合もあります。 Control クラスを継承するクラスには、Control の構造と外観を定義する、ControlTemplate があります。 ControlTemplate プロパティはパブリックであるため、Control に既定とは異なる ControlTemplate を付与できます。 一般的に、Control の外観のカスタマイズには、コントロールの継承ではなく、Control に新しい ControlTemplate を指定します。

よく使用される Button というコントロールについて考えてみます。 Button の主な動作は、ユーザーがクリックしたときに、アプリケーションが一定のアクションを実行することです。 WPF では、Button は既定で浮き出し表示の四角形で表されます。 アプリケーションの開発時、ボタンのクリック イベントを処理する Button の動作は利用し、ボタンのプロパティの変更では実現できないボタンの外観の変更を行いたい場合があります。 このような場合には、新しい ControlTemplate を作成します。

次の例では、ButtonControlTemplate を作成します。 この ControlTemplate では、角が丸くて背景がグラデーションになっている Button が作成されます。 この ControlTemplate には、Background が 2 つの GradientStop オブジェクトを持つ LinearGradientBrush である Border が含まれています。 最初の GradientStop では、データ バインディングを使用して、GradientStopColor プロパティがボタンの背景色にバインドされています。 ButtonBackground プロパティを設定すると、その値の色が最初の GradientStop として使用されます。 データ バインディングの詳細については、「データ バインディングの概要」を参照してください。 この例ではまた、IsPressedtrue のときに Button の外観が変更される Trigger も作成されています。

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

Note

この例が正常に動作するには、ButtonBackground プロパティが SolidColorBrush に設定されている必要があります。

イベントのサブスクライブ

コントロールのイベントをサブスクライブするには、XAML またはコードのいずれかを使用できますが、コードではイベントの処理しかできません。 次の例では、ButtonClick イベントをサブスクライブする方法を示します。

<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

次の例では、ButtonClick イベントが処理されています。

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

コントロールでのリッチ コンテンツ

Control クラスを継承するほとんどのクラスには、リッチ コンテンツを格納する容量があります。 たとえば、Label は、文字列、ImagePanel などの任意のオブジェクトを格納できます。 以下のクラスは、リッチ コンテンツをサポートし、WPF のほとんどのコントロールの基本クラスとして機能します。

これらの基本クラスの詳細については、「WPF のコンテンツ モデル」を参照してください。

関連項目