2013-08-12 7 views
6

私はこのすべての魔法について少し不明です。 Iは、値が格納されているように、依存関係プロパティは、DependencyObjectから継承されます理解されるように:インスタンス自体で依存関係/添付プロパティは内部的にどのように動作し、値はどこに格納されますか?

  • の値が割り当てられている場合(ローカル辞書に)
  • または親要素へのリンクから採取値が指定されていない場合

    protected object GetValue(string propertyName) 
    { 
        if (LocalValues.ContainsKey(propertyName)) 
        { 
         return LocalValues[propertyName]; 
        } 
        return Parent.GetValue(propertyName); 
    } 
    

    この問題を修正しますか?

添付されたプロパティの値はどこに保存されていますか?

Control.FontSizeProperty = TextElement.FontSizeProperty.AddOwner(
typeof(Control), new FrameworkPropertyMetadata(SystemFonts.MessageFontSize, 
FrameworkPropertyMetadataOptions.Inherits)); 

AddOwnerメソッドを呼び出すと、Attachedプロパティは値をインスタンスフィールドに割り当てますか?いつこれが起こり、価値はどこに行くのですか?

ありがとうございます!

答えて

3

WPFのプロパティシステムはかなり複雑です。 MSDNには本当にたくさんの情報がありますが、見つけにくいことがよくあります。 While there are many ways a DependencyProperty can be set、私はあなたが値が格納されているケアする必要があることはよく分かりません。

ローカル値の場合は、DependencyObjectに格納されていると見なすことができます(格納先は気にしないでください)。ただし、文字列に基づいて格納されていないことに注意してください。それは本当にDependencyPropertyのインスタンスに関連付けられています。このため、所有者をプロパティに追加する必要があります。誰かがあなたのコントロールにTextElement.FontSizeを設定した場合、あなたのローカルのFontSizeプロパティを設定するのと同じです。

親からのプロパティの値を継承する限り、は添付プロパティで発生します。 MSDN entryFrameworkPropertyMetadataOptions用:プロパティ値の継承が 非取付け依存関係プロパティのために働くように見えるかもしれません

が、ランタイム ツリー内の特定の要素の境界を通じ 非取付けプロパティの継承動作は未定義です。常にRegisterAttachedを使用して、メタデータに継承を指定するプロパティ を登録してください。

3

依存関係プロパティの値は、プロパティ値を適用するオブジェクト(DependencyObjectから派生したオブジェクト)内に格納されます。

はのは、例えば、あなたのTextElement.FontSizeProperty添付プロパティを見てみましょう:

<StackPanel TextElement.FontSize="20" ... > 
    ... 
</StackPanel> 

XAMLパーサーは、以下にそれを変換します。

内部で
... 
TextElement.SetFontSize(stackPanel, 20); 
... 

public static void SetFontSize(DependencyObject element, double value) 
{ 
    element.SetValue(TextElement.FontSizeProperty, value); 
} 

ので、 TextElementを設定します。stackPanelオブジェクトのFontSizeは、

と同じです。
stackPanel.SetValue(TextElement.FontSizeProperty, value) 

SetValue()はDependencyObjectクラスで定義されたメソッドです。メソッド内では多くの複雑なことが起こりますが、最終的に、依存プロパティの実効値はEffectiveValueEntryという名前の構造体にラップされ、DependencyObject内の次のインスタンスフィールドに格納されます。

private EffectiveValueEntry[] _effectiveValues; 
関連する問題