質問

依存関係プロパティの適切な理由を理解するのに苦労しています。System.Controls.TextBox の "Text" プロパティが通常のプロパティではなく依存関係プロパティであるのはなぜですか?依存関係プロパティであるとどのようなメリットがありますか?

私が達成しようとしていることの 1 つは、他の検証ルールを含む ValidationRules プロパティを UserControl に追加することです。ここのような:

<customControls:RequiredTextBox.ValidationRules>
                        <validators:NotNullOrEmptyValidationRule ErrorMessage="FirstName cannot be null or empty"/>
                    </customControls:RequiredTextBox.ValidationRules>

問題は、ValidationRules プロパティがDependencyPropertyであるべきなのか、それとも通常のプロパティであるべきなのかがわからないことです。

上記のコードでは次のエラーが発生します。

{"Cannot add element to 'ValidationRules'; the property value is null.  Error at object 'LearningWPF.ValidationRules.NotNullOrEmptyValidationRule' in markup file 'LearningWPF;component/addcustomerwindow.xaml' Line 35 Position 66."}

ValidationRules プロパティは次のとおりです。

 public static readonly DependencyProperty ValidationRulesProperty =
            DependencyProperty.Register("ValidationRules",
                                        typeof (Collection<ValidationRule>), typeof (RequiredTextBox),
                                        new FrameworkPropertyMetadata(null)); 

        public Collection<ValidationRule> ValidationRules
        {
            get { return (Collection<ValidationRule>)GetValue(ValidationRulesProperty); }
            set { SetValue(ValidationRulesProperty, value); }
        }
役に立ちましたか?

解決

利点は主に 2 つあります。

まず、依存関係プロパティは使用されたときにのみ作成されます。これは、TextBox クラスがヒープ上の領域を占有する実際のプロパティの数が最小限であるため、メモリ フットプリントが低く、非常に効率的であることを意味します。これは、すべてのコントロールがより具体的な型のコレクションである WPF では特に重要です。これらの内部型のそれぞれが動作と外観を定義するために数十のプロパティを宣言した場合、ボタンのような高レベルのコントロールは、最終的には 100 のプロパティのおおよその内容を含むクラスのサイズになります。

次に、依存関係プロパティは、その作成対象の型以外のオブジェクトに関連付けることができます。これにより、コントロールが Grid.Column プロパティを設定できる場合が可能になり、Grid コントロールはそれを読み取ってレイアウトに使用できます。これは、他のコントロールに必要な小さな機能を提供する何百ものデコレーター クラスが存在しないことを意味します。これは、xmal の方がはるかに直観的で読みやすいことを意味します。


修正された質問の例に対処するために編集されました:

検証プロパティは依存関係プロパティであることから大きなメリットを得ることはできませんが(基本的に、これまでのすべての回答の理由のうち、メモリフットプリントに関する私のコメントが実際に影響していることがわかります)、それは確かに有利ではありませんテキスト ボックスの Text プロパティの場合と同様に、テキスト ボックスをバインドしたり、他の入力に基づいて変更したりする場合でも、依存関係プロパティとして実装します。これに対する私の理由は単純です。得られるものはそれほど多くありませんが、コストもかかりません。カスタム コントロールで基本プロパティを使用していればよかったと思ったことは一度もありません。一方、最初にカスタム コントロールを書き始めたときは、必要な理由から基本プロパティを依存関係に常にアップグレードしていました。いくつかの追加機能。

簡単に言えば、依存関係プロパティは通常のプロパティを定義するのがより複雑ですが、別の理由がない限り、WPF コントロールの事実上の標準として依存関係プロパティを使用します。プロパティとほぼ同じように、フィールドの方が実装が簡単ですが、クラスの標準でもあります。

他のヒント

私が言える主な利点は次のとおりです。

  1. ファーストクラスのデータ バインディングのサポート。
  2. クリーンな添付プロパティのセマンティクス
  3. 「依存する」プロパティ値。

その最後のポイントは、

依存関係プロパティを使用する前は、値にローカル値、アニメーション化可能な値、オーバーライド可能な値、スタイル可能な値、テンプレート可能な値を持たせるには、複数のプロパティ/フィールド/ディクショナリ エントリの宣言と、複雑な状態と優先順位の管理が必要でした。

依存関係プロパティを使用すると、これらすべての機能をすぐに利用できるようになり、宣言するプロパティは 1 つだけになります。

そうは言っても、あなたの場合、これらの機能を利用する必要がない場合は、ValidationRules をDependencyPropertyとして宣言したくないかもしれません。

その場合は、コレクション (空ではないコレクションなど) を別の方法で処理する必要があります。この特定の例では、Reflector を使用して、.NET TextBox が検証コレクションを実装する方法を確認し、コードを再利用またはコピーできるかどうかを確認します。

そうでない限り、車輪を再発明しても意味がありません。 ある あなたのホイールはより良くなるでしょう。私の個人的な経験では、再発明した車輪には何かが欠けていることが多いです ;)。

Martin Harris がすでに指摘したように、DependencyProperties はプロパティ値を辞書にスローすることでメモリ フットプリントを制限できますが、これは、DependencyProperties が登場する前に MSFT によって実行できました (そして私はそう信じています?)。

Martin は Attached Properties についても言及していますが、これらは、DependencyProperties が登場する前にも (少なくともデザイナーでは) 利用可能でした。dependencyProperties を使用した Attached Property の実装は、よりクリーンです。

あなたがプロパティの値を移入するバインディングを使用したい場合は、

依存関係プロパティが必要とされています。それだけで通常の財産だった場合は、たとえば、あなたのビューモデルオブジェクトのプロパティにTextプロパティをバインドすることができません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top