コントロール
Windows Presentation Foundation (WPF) には、Button、Label、TextBox、Menu、ListBox など、ほとんどの 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 の例で示されているものと同じ行と列の定義があります。
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 を作成します。
コントロールのプロパティ値の変更
多くのコントロールには、コントロールの外観を変更するためのプロパティが用意されています。たとえば、Button の Background がそれに該当します。 値プロパティは、XAML でもコードでも設定できます。 次の例では、Button の Background、FontSize、FontWeight の各プロパティを 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 を作成することによって、すべてのコントロールの外観を指定する機能が用意されています。 次の例は、アプリケーションの各 Button に適用される Style を作成しています。Style 定義は、通常、XAML では ResourceDictionary に定義されます。たとえば、FrameworkElement の Resources プロパティがそれに該当します。
<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 クラスを継承するクラスには ControlTemplate があり、これで Control の構造と外観が定義されます。 Control の Template プロパティはパブリックであるため、Control に既定とは異なる ControlTemplate スタイルを与えることができます。 一般的に、Control の外観をカスタマイズするには、コントロールを継承するのではなく、Control に新しい ControlTemplate を指定します。
非常によく使用される Button というコントロールについて考えてみます。 Button の主な動作は、ユーザーがそれをクリックしたときにアプリケーションが一定のアクションを実行できるようにすることです。 WPF では、Button は既定で浮き出し表示の四角形で表されます。 アプリケーションを開発しているとき、Button の動作 (ボタンのクリック イベントの処理) は利用しつつ、ボタンのプロパティの変更だけではできないボタンの外観の変更を行うことにしたとします。 このような場合は、新しい ControlTemplate オブジェクトを作成します。
次の例は、Button の ControlTemplate を作成しています。 この ControlTemplate は、角が丸くて背景がグラデーションになっている Button を作成します。 この ControlTemplate には、Background が 2 つの GradientStop オブジェクトを持つ LinearGradientBrush である Border が含まれています。 最初の GradientStop ではデータ バインディングを使用して、GradientStop の Color をボタンの背景の色にバインドしています。 Button の Background プロパティを設定すると、その値の色が最初の GradientStop として使用されます。 データ バインディングの詳細については、「データ バインディングの概要」を参照してください。 この例はまた、IsPressed が true のときに 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>
メモ |
---|
この例が正常に動作するには、Button の Background が SolidColorBrush に設定される必要があります。 |
イベントのサブスクライブ
コントロールのイベントをサブスクライブするには、XAML またはコードを使用できますが、コードではイベントの処理しかできません。 次の例は、Button の Click イベントのサブスクライブ方法を示しています。
<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);
次の例は、Button の Click イベントを処理しています。
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 に含まれているほとんどのコントロールの基本クラスとして機能します。
ContentControl-- このクラスを継承するクラスには、Label、Button、ToolTip などがあります。
ItemsControl-- このクラスを継承するクラスには、ListBox、Menu、StatusBar などがあります。
HeaderedContentControl-- このクラスを継承するクラスには、TabItem、GroupBox、Expander などがあります。
HeaderedItemsControl-- このクラスを継承するクラスには、MenuItem、TreeViewItem、ToolBar などがあります。
これらの基本クラスの詳細については、「WPF のコンテンツ モデル」を参照してください。