2009-07-23 16 views
21

私は実際には親または子のいずれかの要素にそれらの値を伝える方法を添付プロパティへと少し当惑です。 TextElement.FontFamilyはそのプロパティ(一見下流操作、子供の親)に割り当てられた値を継承する子要素を引き起こします。 Grid.Columnは、特定の位置(一見上流操作、親と子)にその子を表示するために、親項目を引き起こします。 Attachedプロパティの値は、どのようにアップまたはダウンするかを知っていますか?私の考え方は間違っているのでしょうか?それとも、これをすべて見通しにする欠けている部分がありますか?添付プロパティはWPFでどのくらい正確に機能しますか?

<StackPanel TextElement.FontFamily="Wingdings"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 

     <Button Grid.Column="1" Content="My Button"/> 
    </Grid> 
</StackPanel> 

答えて

38

依存性プロパティおよび付属の依存性プロパティがあります。 "Attached Properties"は依存関係プロパティであり、そのようなサポート依存性はproperty value inheritanceです。

基本的な依存関係のプロパティについては、基本的にwpf(論理/視覚的)ツリーの親要素から値を継承していることが非常に大まかです。依存関係プロパティ(添付されているかどうか)は、metadataFrameworkPropertyMetadataOptionsに設定されている場合、その値を「下向き」に継承します。 フラグを継承し、多くの場合これがそうです。

添付プロパティは、DependencyObject.SetValueメソッドを使用して任意のwpfオブジェクト(基本的に、少なくとものDependencyObject)で設定できるプロパティです。このメカニズムの目的は、子オブジェクト自体ではなく、親オブジェクトに必要な情報を他のオブジェクトに「アタッチ」することです。たとえば、Grid.Rowは、レンダリング領域内にアイテムを配置するためにグリッドが必要とする添付プロパティです。

依存プロパティは、wpfオブジェクトシステムによって自動的に "下に"継承されます。

添付されたプロパティは、特定のオブジェクトのコード内で明示的に上向きに調べられます。 Gridの場合、アイテムの配置場所を決定すると、Grid.RowとGrid.Columnの値がそれぞれの含まれている項目のプロパティをチェックします。

また、添付されているオブジェクトを何らかの形で変更するカスタムの添付プロパティを作成する方法もあります(たとえば、Drag'n'Drop functionality via attached properties)。

継承している添付プロパティの良い例はTextElement.FontFamilyです。 Grid.RowプロパティとGrid.ColumnプロパティにはInheritsフラグが設定されていません。

はTextElement.FontFamilyは、リフレクターから:

FontFamilyProperty = DependencyProperty.RegisterAttached("FontFamily", typeof(FontFamily), typeof(TextElement), new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily, FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(TextElement.IsValidFontFamily)); 

Grid.Row、リフレクターから:

RowProperty = DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid), new FrameworkPropertyMetadata(0, new PropertyChangedCallback(Grid.OnCellAttachedPropertyChanged)), new ValidateValueCallback(Grid.IsIntValueNotNegative)); 
+1

興味深く有益です。しかし、このシナリオはどうですか?2x2グリッド(A)には2x2グリッド(B)が含まれています。グリッドBにはボタンがあります。グリッドBにグリッドがある場合。Column Attached Propertyは1に設定されています(グリッドAの親グリッドの2番目の列に表示されます)。AttachedプロパティはグリッドBのButtonに向かってカスケードしないようにしてください。 – Pwninstein

+1

良い質問です。答えに情報を追加しました。 –

+0

恐ろしい!ありがとうございました! – Pwninstein

2

MSDNから:

添付プロパティは、自動的にプロパティを設定する具体的な結果をもたらすか、値がこれまでに別のオブジェクトによって使用されることになるという意味ではありません任意のオブジェクト、上の設定可能ですが。一般に、添付プロパティは、さまざまな可能なクラス階層または論理関係から来るオブジェクトが、それぞれが添付プロパティを定義する型に共通の情報を報告できるように意図されています。典型的には、添付プロパティを定義する型は、これらのモデルのいずれかを次の

  • が の値を設定します要素 の親要素とすることができるように取り付けられ プロパティを定義型が設計されています添付の プロパティ。次に、タイプは、オブジェクトツリー構造に対して 子オブジェクトを内部ロジック で繰り返し、 が値を取得し、何らかの方法でこれらの値に作用します。添付 プロパティを定義

  • タイプが可能 親要素およびコンテンツモデルの様々な子 要素として使用されます。

  • 添付 プロパティを定義タイプは、サービスを表します。その他 種類が付属 プロパティの値を設定します。次に、 がプロパティを設定した要素がサービスの コンテキストで評価されると、 プロパティ値が サービスクラスの内部ロジックを通じて取得されます。

親定義の添付プロパティのアン例

親要素が子要素のコレクションをサポートし、また動作を実装する場合、WPFが添付プロパティを定義する最も一般的なシナリオでありますビヘイビアの詳細は、各子要素ごとに個別に報告されます。

DockPanelはDockPanel.Dock添付プロパティを定義し、DockPanelはそのレンダリングロジック(具体的にはMeasureOverrideとArrangeOverride)の一部としてクラスレベルのコードを持っています。 DockPanelインスタンスは、直下の子要素のいずれかがDockPanel.Dockの値を設定しているかどうかを常にチェックします。そうである場合、それらの値は、その特定の子要素に適用されるレンダリングロジックの入力になります。ネストされたDockPanelインスタンスはそれぞれ独自の直接的な子要素コレクションを扱いますが、その動作はDockPanelがDockPanel.Dock値をどのように処理するかに固有の実装です。理論的には、直接の親を越えて要素に影響する添付プロパティを持つことは可能です。 DockPanelの場合。Dock添付プロパティは、DockPanel親要素がない要素に設定され、エラーまたは例外は発生しません。これは、単にグローバルプロパティ値が設定されていることを意味しますが、情報を消費する可能性のある現在のDockPanelの親はありません。

0

簡単な言葉では、これは(私が間違っている場合は、私を修正してください、私はそれを理解する方法です)。

オブジェクト(A)は別のオブジェクト(B)にアタッチするプロパティを実装します(オブジェクトBはこの「アタッチ可能」プロパティの存在についても知らない)。オブジェクトBはDependencyObjectから継承する必要があります。

オブジェクトAは、他のオブジェクトの "attachable"プロパティであるA.GetAttachedProperty(B)をチェックする静的メソッドも実装しています。

BにAの添付プロパティがある場合、A.GetAttachedPropertyはその値を読み取り、返します。さもなければ、Aはそれを読み込もうとし、そこにないのでnullを返します。

関連する問題