このページは役に立ちましたか。
このページのコンテンツについての ご意見をお待ちしております
その他にご意見はありますか。
残り 1500 文字
エクスポート (0) 印刷
すべて展開
情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Windows Phone 8 の依存関係プロパティ

2014/06/18

対象: Windows Phone 8 および Windows Phone Silverlight 8.1 | Windows Phone OS 7.1

Windows Phone には、CLR プロパティの機能を拡張するために使用できるサービスのセットが用意されています。通常、これらのサービスをまとめて Windows Phone プロパティ システムと呼びます。Windows Phone プロパティ システムによってサポートされるプロパティは、依存関係プロパティとして知られています。ここでは、Windows Phone プロパティ システムと依存関係プロパティの機能について説明します。また、依存関係プロパティ メタデータなどの依存関係プロパティの特殊な側面や、カスタム クラスで独自の依存関係プロパティを作成する方法についても説明します。

このトピックは、次のセクションで構成されています。

ここでは、CLR およびオブジェクト指向プログラミングに関する基礎知識があることを前提にしています。このトピックの例を理解するには、XAML についての理解があり、 ベースのアプリの記述方法を理解していることも必要です。

Windows Phone では通常、依存関係プロパティは CLR プロパティとしても公開されます。基本的なレベルでは、これらのプロパティと直接対話でき、これらのプロパティが依存関係として実装されることを認識することはありません。ただし、Windows Phone プロパティ システムの一部またはすべての機能を利用できるように、依存関係プロパティの機能に精通しておく必要があります。

依存関係プロパティの目的は、他の入力の値に基づいてプロパティの値を計算する方法を提供することです。他の入力には、ユーザー設定などの外部プロパティ、データ バインディングやアニメーション/ストーリーボードなどのジャスト イン タイム プロパティ判定機構、リソースやスタイルなどの多目的のテンプレート、オブジェクト ツリー内の他の要素との親子のリレーションシップから判断される値などがあります。また、依存関係プロパティを実装して、他のプロパティに対する変更を反映できるコールバックを提供できます。

何らかの方法で UI に表示される DependencyObject の Windows Phone 型の場合、オブジェクトに対して設定可能なプロパティのほとんどは依存関係プロパティであるため、アニメーションをサポートできます。FrameworkElement 派生型の場合、依存関係プロパティでスタイルもサポートしています。読み取り専用のプロパティが依存関係プロパティである可能性は低いですが、WPF の互換性のために依存関係プロパティとして実装されている読み取り専用のプロパティも一部あります。一般的ではありませんが DependencyObject の設定可能なプロパティが依存関係プロパティではない場合、そのプロパティはアニメーション、データ バインディング、または FrameworkElement スタイル設定をサポートできません。

API リファレンスでは、特定の Windows Phone プロパティが依存関係プロパティとして実装されるかどうかを明確に確認できます。「解説」セクションに "依存関係プロパティの識別子フィールド" という表記と、名前の末尾が Property になっている API (フィールド) へのリンクがある場合、そのプロパティは依存関係プロパティです。対応する方法でフィールドを公開し、それに名前を付けるこの規則には、カスタム依存関係プロパティまたはサードパーティの依存関係プロパティも従う必要があります。たとえば、型として定義される Ticks という名前のプロパティがあり、同じ型で公開されている TicksProperty という名前のフィールドがある場合 (かつフィールドが DependencyProperty 型の場合)、Ticks は依存関係プロパティです。

依存関係プロパティおよび のプロパティ システムは、プライベート フィールドでプロパティをサポートする標準パターンの代替実装として、プロパティをサポートするプロパティ ストアを提供することによって、CLR で定義されたプロパティ機能を拡張します。ストア内の各プロパティを識別する型の名前は DependencyProperty です。Windows Phone のプロパティ システムを定義するもう 1 つの重要な型は DependencyObject です。DependencyObject では、依存関係プロパティを登録および所有できる基本クラスを定義します。これは、依存関係プロパティ値をストア内に保持する DependencyObject です。

依存関係プロパティについて説明するときにこのドキュメントで使用する用語の概要を次に示します。

  • 依存関係プロパティ: DependencyObject に存在するプロパティ。DependencyObject プロパティ ストアによって格納され、所有する DependencyObjectDependencyProperty 識別子によって識別されます。

  • 依存関係プロパティの識別子: DependencyProperty のインスタンス。Windows Phone コア API の既存の依存関係プロパティの場合、このインスタンスは通常、依存関係プロパティを保持する同じ DependencyObject 型のメンバーである、public static readonly フィールドとして公開されます。カスタム依存関係プロパティの場合、このフィールドは依存関係プロパティの登録時に戻り値として取得されます。その後、このフィールドをクラスのメンバーとして格納する必要があります。また、依存関係プロパティの識別子フィールドは、Windows Phone のプロパティ システムの基盤を公開する GetValueSetValue などの API に加えて、識別子 (たとえば、PropertyPath コンストラクターの一部のシグネチャ、または Setter.Property) で依存関係プロパティが指定される他の API でも、パラメーターとして使用できます。

  • CLR ラッパー: CLR 型システム (アーキテクチャの下位レベルで動作) から参照できる、プロパティの実際の get 実装および set 実装。これらの実装は、依存関係プロパティの識別子を GetValue および SetValue の呼び出しで使用し、Windows Phone プロパティ システムを使用してプロパティのサポートを提供することによって、その識別子を組み込みます。GetValue または SetValue の呼び出しが、get 実装および set 実装のすべてを占めている必要があります。ラッパーは呼び出し元に対して便利なだけではありません。多くのシナリオに欠かせないリフレクションや CLR 型システムを基盤として使用するプロセスまたはツールに対する依存関係プロパティも公開します。

次の例では、カスタム IsSpinning 依存関係プロパティを定義し、DependencyProperty 識別子とサポートされるプロパティの関係を示します。


public static readonly DependencyProperty IsSpinningProperty = 
    DependencyProperty.Register(
    "IsSpinning", typeof(Boolean),
    typeof(SilverlightExampleClass), null
    );
public bool IsSpinning
{
    get { return (bool)GetValue(IsSpinningProperty); }
    set { SetValue(IsSpinningProperty, value); }
}


メモメモ:

 前の例の目的は、カスタム依存関係プロパティを作成する方法の完全な例を示すことではありません。依存関係プロパティの概念を示すことが目的です。これは、概念について学ぶには、代表的なコードを確認することが最も良い方法であるためです。

一般的には、Windows Phone のプロパティはコードまたは XAML で設定できます。通常、コードと XAML の相違点として、プロパティが依存関係プロパティによってサポートされるかどうかは関係ありません。どちらの場合も、プロパティが設定可能なときにそれを設定すると、そのプロパティ ストア内でプロパティを保持するオブジェクトに値が設定されますが、そのストアは実装されます。ただし、コードでのみ設定可能なプロパティがあります。多くの場合、これはプロパティが受け取る型を XAML で表現できないためです。また、通常は依存関係プロパティでのみ動作し、CLR プロパティでは動作しない特定のプロパティ関連の機構が存在します。これは、そうした機構では、DependencyProperty を型として使用するためです。この例として、スタイルおよびテンプレートで使用される Setter.Property があります。

XAML でのプロパティ値の設定

XAML は、プロパティを設定するためのさまざまな構文形式をサポートします。最も単純な形式は文字列属性です。特定のプロパティに対してどの構文を使用するかは、プロパティで値として使用される型、および型コンバーターの有無などのその他の要素によって決定されます。プロパティ設定の XAML 構文の詳細については、「Windows Phone 8 の XAML」を参照してください。通常、XAML の特定のプロパティで使用する構文は、リファレンス ページの「構文」セクションで説明されています。また、「使用例」セクションでも説明されている場合があります。

構文の点では、Windows Phone XAML パーサーは標準 CLR プロパティと依存関係プロパティでサポートされるプロパティとを区別しません。ただし、XAML プロパティ システムの操作の中には理解しておく必要のあるものもあります。

  • 依存関係プロパティだけが、Binding または TemplateBinding マークアップ拡張機能を使用する値を受け入れることができます。これらの値を提供する役目を果たしているのは、XAML パーサー自体ではなく、プロパティ システムであるためです。

  • Windows Phone XAML パーサーでは、Setter スタイル値を設定する場合は CLR ラッパーをバイパスします。

  • StaticResource のマークアップ拡張機能は、XAML で設定される任意のプロパティで使用できます。プロパティは依存関係プロパティである必要はありません。ただし、このプロパティでは、XAML の別の場所で定義されるように Windows Phone リソース ディクショナリ外から共有できる値を使用する必要があります。これは厳密に言うと、プロパティ システムで定義された動作ではありません。

コードでのプロパティの設定

依存関係プロパティの値をコードで設定するには、通常、CLR ラッパーによって公開される標準 CLR プロパティを使用するだけで済みます。

scratchCanvas.Width = 200; //scratchCanvas is an existing Canvas instance

プロパティ値を取得する場合も、基本的に標準プロパティを使用します。

double whatWidth = scratchCanvas.Width;

また、プロパティ システム API GetValue および SetValue を直接呼び出すこともできます。これは通常、既存のプロパティを使用する場合は不要ですが (ラッパーの方が便利で、開発者ツール用のより優れたプロパティが公開されます)、特定のシナリオではプロパティ システム API を直接呼び出す方法が適しています。この使用方法は、依存関係オブジェクトの実際のプロパティ ストアが DependencyObject クラスに実装され、DependencyObject のすべてのインスタンスで利用できるということをよく示しています。

また、最初に読み込まれる XAML でプロパティを設定した後、ランタイム オブジェクト ツリーにアクセスすることによって、コードでアクセスすることもできます。その際のアクセス方法には、分離コード内のイベント ハンドラー、エントリ ポイントとしての FindName、ルートからのオブジェクト ツリーの走査などを使用できます。

依存関係プロパティは、フィールドによって補足されるプロパティとは対照的に、プロパティの機能を拡張する機能を提供します。多くの場合、このような機能のそれぞれが、Windows Phone 全体の機能セットの特定の機能を表したりサポートしたりします。

データ バインディング

設定する依存関係プロパティが DependencyObject サブクラスに存在する限り、データ バインディングを使用して依存関係プロパティで値を設定できます。データ バインドは、XAML で特定のマークアップ拡張機能構文を介して機能するか、コードで Binding オブジェクトを介して機能します。データ バインディングを使用すると、プロパティ値の最終的な決定が、データ ソースから値が取得される実行時まで延期されます。

XAML でバインディングを使用して、テキスト ブロックのテキストを設定する例を次に示します。バインディングでは、継承されたデータ コンテキストおよびオブジェクト データ ソース (この例には示されていません) が使用されます。

    <Canvas>
      <TextBlock Text="{Binding Team.TeamName}"/>
    </Canvas> 

XAML ではなく、コードを使用してバインディングを確立することもできます。「SetBinding」を参照してください。

メモメモ:

バインディングは、依存関係プロパティ値の優先順位を処理するために、ローカル値として扱われます。つまり、別のローカル値を設定すると、バインディングがなくなります。

バインディング ソース、バインディング ターゲット

プロパティをバインディング ソースとして使用する場合は、依存関係プロパティでなくてもかまいません。バインディング ソースとして、任意の CLR プロパティを使用できます。ただし、プロパティをバインディング ターゲットとして使用する場合は、依存関係プロパティである必要があります。

コードでバインディングを設定している場合、SetBinding API は FrameworkElement に対してのみ定義されている点に注意してください。ただし、バインディング定義は BindingOperations を使用して作成できるため、どのような DependencyObject プロパティでも参照することができます。

コードであれ XAML であれ、DataContextFrameworkElement プロパティです。(ターゲット プロパティを持つ) 子オブジェクトが FrameworkElement ではないためにそれ自身の DataContext 値を保持していなかったとしても、親から子へのプロパティの継承によって、バインディング システムは親要素に存在する DataContext を解決することができます。ただし、DataContext を設定、保持するためには、親要素が FrameworkElement であることが必要です。そうでない場合は、DataContext が null であっても機能できるような形で、バインディングを定義する必要があります。

メモメモ:

Windows Phone を対象としたアプリは、FrameworkElement のターゲット プロパティにのみバインドすることができます。Windows Phone ではこの点が強化され、DependencyObject のあらゆる依存関係プロパティに対するバインディングに対応しました。

一方向または双方向のバインディングを有効にするためには、バインディング システム (とターゲット) への伝播をつかさどる変更通知が、ソース プロパティによってサポートされている必要があります。つまり、カスタム CLR バインディング ソースの場合、このプロパティは、INotifyPropertyChanged をサポートしている必要があります。コレクションの場合は、INotifyCollectionChanged をサポートしている必要があります。一部のクラスでは、これらのインターフェイスのいずれかが実装でサポートされているので、データ バインディング シナリオのための基本クラスとして役立ちます。このようなクラスの例には ObservableCollection<T> があります。

Windows Phone でのデータ バインディングの詳細およびデータ バインディングをプロパティ システムに関連付ける方法については、「Windows Phone 8 のデータ バインディング」を参照してください。

スタイル

スタイルおよびテンプレートは、依存関係プロパティとして定義されるプロパティに関する 2 つの主なシナリオです。スタイルは、アプリのユーザー インターフェイス (UI) を定義するプロパティを設定する際に特に役立ちます。スタイルは、通常、XAML でアプリ レベルのリソース ディクショナリまたはページ レベルのリソース ディクショナリのどちらかとして、リソースとして定義されます。または、generic.xaml のような Windows Phone アプリ モデル全体で特定の役割を果たす XAML ファイル内で定義されます。スタイルには通常、特定のプロパティの "setter" が含まれるため、スタイルはプロパティ システムと対話します。通常、この方法で設定される最も重要なプロパティは、ControlTemplate です。このプロパティは、Control のほとんどの表示形式と表示状態を定義します。

スタイルの詳細、および Style を定義し、setter を使用する XAML の例については、「Style」を参照してください。

アニメーション

アニメーション化するためには、アニメーションのターゲット プロパティは依存関係プロパティである必要があります。また、そのターゲット プロパティの値の型は、既存の Timeline から派生したアニメーション型のいずれかでサポートされている必要があります。

アニメーションが適用されて実行されると、アニメーション化された値は、それ以外の場合のプロパティの値 (ローカル値など) よりも高い優先順位で動作します。アニメーションにはオプションの動作もあり、アニメーションが停止しているように見えていても、HoldEnd 動作を使用して、アニメーションをプロパティ値に適用できます。

Windows Phone のアニメーションは、1 回のみの視覚的装飾要素または繰り返される視覚的装飾要素を作成する従来のアニメーションの使用方法のためだけのものではありません。特定の刺激に基づいて個々のプロパティまたはコントロール全体の状態を設定できるステート マシンと考えることができます。この原則は、コントロールの VisualStateManager 状態モデルの一部としてアニメーションを使用して実現されます。

プロパティ変更動作

プロパティ変更動作は、依存関係プロパティという用語で "依存関係" という言葉が使用されている主な理由の 1 つです。他のプロパティの値によって影響を受ける可能性のあるプロパティで有効な値を維持することは、多くのプラットフォームにおいて、開発上の難しい問題です。Windows Phone の依存関係プロパティ システムには、各依存関係プロパティのプロパティ値が変更されるたびに呼び出されるコールバックを指定する機能が組み込まれています。このコールバックを使用して、一般的な同期方法で、通知または関連プロパティ値の変更を実行できます。

Windows Phone の多くの既存の依存関係プロパティには、プロパティ変更動作があります。また、このような動作をカスタム依存関係プロパティに追加し、独自のプロパティ変更コールバックを実装することもできます。

既定値と ClearValue

依存関係プロパティには、プロパティ メタデータの一部として既定値を定義できます。通常のプロパティと依存関係プロパティの既定値の相違点は、値の優先順位の他の決定要因がなくなるたびに既定値が適用されることです (依存関係プロパティ値の優先順位については、次のセクションで説明します)。たとえば、ユーザーが意図的にプロパティからテンプレートまたはアニメーションを削除しても、削除後に適切な既定値がこれらのプロパティ値に適用されるようにしたい場合があります。依存関係プロパティの既定値では、あらゆる場合で特に設定することなく、適切な値が適用されます。

既にローカル値を設定してある場合は、意図的に既定値を設定する必要があります。プロパティを設定しても単にローカル値が再度設定されるだけで、既定値は復元されません。値を既定値に再度リセットし、ローカル値の優先順位より低い優先順位の値を再度有効にするには、プロパティの ClearValue を呼び出します。

依存関係プロパティの値を取得する場合、Windows Phone プロパティ システムに関係するプロパティに基づく入力のいずれかを介して、そのプロパティに設定された値を取得する可能性があります。Windows Phone のプロパティの値の取得方法に関するさまざまなシナリオが予測可能な方法で相互作用できるように、依存関係プロパティ値の優先順位が存在しています。

たとえば、スタイルとテンプレートはプロパティ値を設定する開始点を共有するように設計されているので、コントロールの外観も共有されます。ただし、特定のコントロール インスタンスでは、背景色を変えたり、コンテンツとして異なるテキスト文字列を使用したりするなど、コントロールのプロパティ固有の部分を共通のテンプレートから変更する場合があります。Windows Phone のプロパティ システムでは、スタイルおよびテンプレートで指定される値より高い優先順位をローカル値で使用して、このシナリオを実現します。

添付プロパティは、Windows Phone で特殊な XAML 構文をサポートするプロパティの一種です。多くの場合、添付プロパティは CLR プロパティ階層と直接対応していません。添付プロパティの一般的な目的は、親要素と子要素がどちらも、汎用の型システムで実行可能なメンバーとしてそのプロパティを所有しない場合でも、子要素が親要素にプロパティ値を報告できるようにすることです。Windows Phone での添付プロパティの主なシナリオの 1 つは、子要素から親要素に UI でどのように表示するかを通知できるようにすることです。このシナリオの例については、「Canvas.Left」を参照してください。

表示:
© 2015 Microsoft