試してみよう : カスタム WPF コントロールの作成
Microsoft Expression Blend には、Windows Presentation Foundation (WPF) アプリケーションで使用できるさまざまなシステム コントロールや簡易スタイルが用意されています。これらのコントロールやスタイルが特定の要件に適合しない場合は、カスタム コントロールを作成できます。カスタム コントロールを作成するには、いずれかの System.Windows.Controls クラスから継承する Microsoft .NET クラスを作成します。
メモ : |
---|
このトピックには、Windows Presentation Foundation アプリケーションの情報が含まれています。Microsoft Silverlight 1.0 の詳細については、「Silverlight 1.0 の概要」および Silverlight ラーニング センター (英語の可能性あり) を参照してください。また、Expression Blend 2 に付属の Silverlight 1.0 サンプルも参照してください。一部のサンプルでは、JavaScript クラスを使用して再利用可能なオブジェクトを定義します。[ヘルプ] メニューの [ようこそ画面] をクリックし、[サンプル] タブを選択します。MagnifyingGlass、ButtonGallery、BlendPlayer の各サンプルは、Silverlight 1.0 サンプルです。 |
イメージを表示するためにイメージ ファイルのパスを保持する新しいプロパティを含むカスタム ボタン コントロールを作成する手順を次に示します。コードを使用せず、したがってカスタム プロパティを持たないユーザー コントロールを作成する例については、「試してみよう : WPF ユーザー コントロールの作成」を参照してください。
XAML とコードの例を含むカスタム コントロールの詳細については、MSDN の「Windows Presentation Foundation」のセクションにある「コントロールの作成の概要」および「DependencyProperty クラス」を参照してください。
カスタム コントロールを定義するには
[プロジェクト] パネルでファイル Window1.xaml を検索し、展開して、プロジェクトのコードビハインド ファイル (Window1.xaml.cs) を表示します (プロジェクトを作成するときに言語として Microsoft Visual Basic を選択すると、コードビハインド ファイル名は Window1.xaml.vb となります)。コードビハインド ファイルをダブルクリックして開き、編集します。
メモ : コードビハインド ファイルは Microsoft Visual Studio 2008 で開かれます (インストールされている場合)。このアプリケーションがインストールされていない場合、コードビハインド ファイルは、コードビハインド ファイルの拡張子に対応付けられているアプリケーションで開きます。たとえば、.cs ファイルまたは .vb ファイルをメモ帳で開くように設定していると、Expression Blend ではメモ帳でファイルが開きます。コードビハインド ファイルを開く方法については「コードビハインド ファイルの編集」を参照してください。
Window1.xaml.cs ファイルで、ファイルの最後にある閉じかっこ (}) の直前に、次のクラス定義のソース コードを貼り付けます (Visual Basic では、End Namespace の直前または最後の End Class の直後に、適切なコードを貼り付けます)。
public class ImageButton : Button { public ImageSource Source { get { return base.GetValue(SourceProperty) as ImageSource; } set { base.SetValue(SourceProperty, value); } } public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImageButton)); }
Class ImageButton Inherits Button Public Property Source() As ImageSource Get Return CType(MyBase.GetValue(SourceProperty), ImageSource) End Get Set(ByVal value As ImageSource) MyBase.SetValue(SourceProperty, value) End Set End Property Public Shared ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register("Source", GetType(ImageSource), GetType(ImageButton)) End Class
変更したコードビハインド ファイルを保存し、Visual Studio またはファイルの編集に使用したアプリケーションを閉じます。
ヒント : ImageButton クラスは、依存関係プロパティのパターンを示したものです。外部的に、このクラスは、ImageSource 型の Source という名前の通常の共通言語ランタイム (CLR、つまり .NET) プロパティを公開します。また、SourceProperty という読み取り専用の依存関係プロパティ フィールドも登録して公開し、依存関係プロパティに関して Source プロパティ用に CLR アクセサを実装します。CLR プロパティを登録済み依存関係プロパティで補助することで、WPF はプロパティに多様なサービスを提供できるようになります。提供できるサービスには、スタイル設定、データ バインド、値の継承、既定値、アニメーションなどがあります。WPF には、コントロール テンプレート内からプロパティ値にバインドするテンプレートのバインドという機能もあります。このチュートリアルでは、実行中のテンプレートのバインドについて説明します。
ヒント : カスタム コントロールのクラス定義のソース コードを、別のソース コード ファイルに保存することもできます。上記の 2 つの手順の代わりに、ImageButton.cs という新しいファイルを作成し、ソース コード、名前空間の宣言、およびドキュメントのコードビハインド ファイルの using ディレクティブの同じセットをこのファイルに貼り付け、新しいファイルをプロジェクトに追加することもできます ([プロジェクト] メニューの [アイテムの追加] をクリックします)。
新しい ImageButton コントロールが [アセット ライブラリ] に表示されるようにプロジェクトを構築する必要があります。Expression Blend の [プロジェクト] メニューで、[プロジェクトのビルド] をクリックします (または Ctrl + Shift + B キーを押します)。エラーが発生せずにビルドが完了することを確認します。
Expression Blend での Window1.xaml の編集作業に戻ります。
Expression Blend の左側にある [ツールボックス] の [アセット ライブラリ] ボタン をクリックします。
[アセット ライブラリ] が開き、ドキュメントに配置できるすべてのコントロール、パネル、および要素が表示されます。
[カスタム コントロール] タブの一覧から、ImageButton コントロールを選択します。
[アセット ライブラリ] ボタンの上部にある [ツールボックス] アイコンには、指定した ImageButton コントロールが設定されました。既に選択されている状態であるため、アートボードにコントロールを描画できます。
メモ : カスタム コントロールを [アセット ライブラリ] の [カスタム コントロール] タブに表示するには、プロジェクトにソース コードを追加してビルドを実行 (Ctrl + Shift + B キー) する必要があります。
ImageButton を描画するには、ツールボックスで ImageButton アイコンを選択した状態で、アートボードをクリックし、ドキュメント内に境界ボックスを描画します。
ImageButton がアートボードにレンダリングされ、[ImageButton] "ImageButton" という ImageButton 要素が、[組み合わせ] パネルの [オブジェクトとタイムライン] にある [LayoutRoot] の子要素として表示されます。
先頭に戻る
カスタム コントロールのスタイルを変更するには
すべての ImageButton 要素のコントロール テンプレートを作成するには、新しい ImageButton を右クリックし、[コントロール パーツ (テンプレート) の編集] をクリックして、[コピーの編集] をクリックします。
[スタイル リソースの作成] ダイアログ ボックスが表示されます。
[スタイル リソースの作成] ダイアログ ボックスの [リソース名 (キー)] フィールド (最初のラジオ ボタンの横にあるテキスト ボックス) に、「ImageButtonStyle」と入力します。
リソース ディクショナリのテンプレートに名前が設定されます。これで、任意の ImageButton 要素に対してテンプレートとして設定できます。
メモ : コントロールに適用されるスタイルがコントロールの外観 (パーツ) と動作の両方を含むよう、コントロール テンプレートはスタイルの内部にラップされています。
[定義元] フィールドで [このドキュメント] をオンにし、ドロップダウン リストで [Window: Window] が選択されていることを確認します。
[定義元] フィールドは、新しいテンプレートを定義するリソース ディクショナリを示します。[Window: Window] を選択するのは、テンプレートがウィンドウ内のすべての ImageButton コントロールから見えるようにするためです。
[OK] をクリックします。
ここまでの操作で、すべての ImageButton 要素の既定のコントロール テンプレートがコピーされ、ImageButtonStyle という名前の新しい ControlTemplate として保存されました。新しいテンプレートがリソース ディクショナリに配置されています。このテンプレートは、[リソース] パネルの [Window] ノードで確認できます。
新しいテンプレートを作成すると、Expression Blend は、新しいテンプレートを表示および編集できるモードになります。[組み合わせ] パネルの [オブジェクトとタイムライン] にある新しい要素ツリーの上の "テンプレート" という語は、編集している現在のスコープを示します。テンプレートには、このテンプレートを使用する ImageButton の Content プロパティ値を自動的に表示する ContentPresenter 要素が含まれます。
ヒント : テンプレートの編集モードを終了し、ドキュメントのスコープに戻るには、[上へスコープ] ボタン をクリックします。このボタンは、ImageButtonStyle という語の横にある要素ツリーの上にあります。
既存のテンプレートの場合、テンプレートの編集モードに戻るには、[組み合わせ] パネルの [オブジェクトとタイムライン] でテンプレートを編集する要素を右クリックし (この例では [ImageButton] "ImageButton" 要素)、[コントロール パーツ (テンプレート) の編集] をクリックして、[テンプレートの編集] をクリックします。
[オブジェクトとタイムライン] で ContentPresenter オブジェクトを右クリックし、[グループ化設定] をポイントし、[グリッド] をクリックします。
ContentPresenter オブジェクトは、新しい Grid オブジェクトの子要素になります。Grid オブジェクトが存在しない場合、2 つ目の子要素をテンプレートに追加することはできません。クロム オブジェクトには 1 つの子要素しか含めることができないためです。
[オブジェクトとタイムライン] で Grid オブジェクトを選択した状態で、[プロパティ] パネルの [レイアウト] カテゴリにある [Width] と [Height] のプロパティを検索します。各プロパティの横にある [詳細プロパティ オプション] ボタンをクリックし、[リセット] をクリックします。
グリッドを 2 つの列に分割するには、[オブジェクトとタイムライン] でグリッド オブジェクトをダブルクリックしてグリッドをアクティブにし、ツールボックスで [選択内容] ツール を選択している状態で、アートボードの Grid の上部にある濃い青のルーラー領域にマウス ポインタを移動します。オレンジ色の列ルーラーがマウス ポインタに従って移動します。このルーラーは、クリックしたときに新しい列デバイダを配置する場所を示します。
クリックすると、Grid の途中で新しい列デバイダが作成されます。
青の列デバイダが Grid 内に表示されます。
[アセット ライブラリ] の [コントロール] タブで [Image] ツール を選択します ([すべて表示] チェック ボックスをオンにします)。[組み合わせ] パネルの [オブジェクトとタイムライン] で Grid 要素がアクティブになっている状態で、Grid の右側の列内に新しい Image を描画します。
[オブジェクトとタイムライン] で新しい Image 要素を選択した状態で、[プロパティ] パネルの [共通プロパティ] の設定内容を確認します。Source プロパティの右側にある [詳細プロパティ オプション] ボタンをクリックし、[テンプレートのバインド] をポイントして、[ソース] をクリックします。
これで、Image の Source プロパティが、このテンプレートを使用する ImageButton の Source プロパティに対してテンプレート バインドされました。
テンプレートの編集は完了しました。終了してルート要素のスコープに戻るには、[オブジェクトとタイムライン] で [上へスコープ] をクリックします。
[オブジェクトとタイムライン] で [ImageButton] を選択した状態で、[プロパティ] パネルの [その他] カテゴリにある Source プロパティを探します。このプロパティに、コンピュータ上のイメージ ファイルのパスを設定します。
イメージが ImageButton コントロールの右側に表示されます。
先頭に戻る
他のカスタム コントロールにスタイルを適用するには
[アセット ライブラリ] の [カスタム コントロール] タブで、[ImageButton] コントロールを選択します。アートボードに新しい ImageButton コントロールを描画します。
描画した ImageButton を右クリックし、[コントロール パーツ (テンプレート) の編集] をクリックして、[リソースの適用] をクリックします。次に、スタイル名として ImageButtonStyle をクリックします。
ImageButtonStyle が新しい ImageButton コントロールに適用されます。[プロパティ] パネルの [その他] カテゴリで [Source] プロパティを検索し、コンピュータ上のイメージ ファイルのパスを設定します。
メモ : 代わりに、テンプレートを使用して既にスタイルが適用されている ImageButton をアートボードに追加することもできます。[アセット ライブラリ] の [ローカル スタイル] タブで ImageButtonStyle を選択した後、スタイルを適用した ImageButton をアートボードに描画します。
先頭に戻る
詳細 : カスタム プロパティの説明を適用する
コードビハインド ファイル (Window1.xaml.cs) の先頭に、System.ComponentModel 名前空間への参照を追加します。
以下で使用する説明属性とカテゴリ属性は、この名前空間で定義されています。
クラス定義の前に、次の行 (太字) を貼り付けます。
[Description("Represents a custom button control that responds to a Click event. Displays an image using a custom Source property if the Source property is bound to an Image in the template.")] public class ImageButton : Button
<Description("Represents a custom button control that responds to a Click event. Displays an image using a custom Source property if the Source property is bound to an Image in the template.")> _ Class ImageButton
カスタム プロパティ定義の前に、次の行 (太字) を貼り付けます。
[Description("The image displayed in the button if there is an Image control in the template whose Source property is template-bound to the ImageButton Source property."), Category("Common Properties")] public ImageSource Source
<Description("The image displayed in the button if there is an Image control in the template whose Source property is template-bound to the ImageButton Source property."), Category("Common Properties")> _ Public Property Source() As ImageSource
Category 属性は、[プロパティ] パネルでプロパティを表示する場所を構成します。
プロジェクトをリビルドします (Ctrl + Shift + B キー)。
ImageButton の Source プロパティが [プロパティ] パネルの [共通プロパティ] カテゴリに表示されるようになり、[アセット ライブラリ] のプロパティおよびコントロールの上にマウス ポインタを移動すると、ツールヒントに説明が表示されます。
先頭に戻る
詳細 : 既定の画像を表示するようにコントロールを構成する
コントロールをアートボードに描画するとき、したがってデザイン モードのときにプロパティを既定値に設定するコードを、カスタム コントロールのコンストラクタに追加できます。次の手順を使用して設定するプロパティは、アートボードでの表示に対してのみ適用され、アプリケーションの実行時の表示には適用されません。コンテンツがデータベースや Web サービスから取得される場合など、デザイン モードのときにはコントロールのコンテンツを利用できず、アプリケーションの実行時には利用できる場合に役に立ちます。この場合、アートボード上の ImageButton の Source プロパティは、明示的に設定されるまでは、プロジェクトのイメージ ファイルの名前に設定されます。
コードビハインド ファイル (Window1.xaml.cs) で、プロパティ定義の後に、次のコード行 (太字) を貼り付けます。
メモ : 次のコードのファイル名 (Sunset.jpg) を、実際のプロジェクトでのイメージ ファイルの名前に変更してください。プロジェクトにイメージ ファイルを追加するには、[プロジェクト] パネルの [ファイル] でプロジェクト名を右クリックし、[既存のアイテムを追加] をクリックします。
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImageButton)); // Constructor:public ImageButton(){ if (DesignerProperties.GetIsInDesignMode(this)) { this.Source = new BitmapImage(new Uri("Sunset.jpg", UriKind.Relative)); }}
Public Shared ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register("Source", GetType(ImageSource), GetType(ImageButton)) Public Sub New() If DesignerProperties.GetIsInDesignMode(Me) Then Me.Source = New BitmapImage(New Uri("Sunset.jpg", UriKind.Relative)) End IfEnd Sub
プロジェクトをリビルドします (Ctrl + Shift + B キー)。
作成したスタイルを使用するアートボードに ImageButton を追加すると、ボタンに既定のイメージが表示されるようになります。
メモ : デザイン モードでは、Source プロパティに他の値を設定することはできません。
先頭に戻る