0

外部で定義された、論理的に排他的な(ビジネス上)アタッチされたプロパティが2つあり、どちらも継承可能です。読んでいるDependencyObjectに最も近い設定に応じて、以下に示すように、ロジックでどちらを使用するかが決まります。

注:継承されていることを知りたくありません。これは、を介して実行できますどこDependencyPropertyHelper.GetValueSourceから取得したかを知りたいので、優先順位を決定できます。

次のビジュアルツリー階層と添付プロパティについて考えてみます。

Root // <-- AProp1 first set here
    Child
        GrandChild // <-- AProp2 first set here
            GreatGrandChild // <-- AProp1 re-applied here
                GreatGreatGrandChild
  • ルートの場合、AProp1が単独で設定されるため、AProp1を使用します。

  • 子の場合、AProp1は継承されるため、引き続きAProp1を使用します。

  • GrandChildの場合、AProp2が設定されますが、継承のおかげでAProp1にも値があります。ただし、AProp2はこのオブジェクトに直接設定されているため(つまり、「0」レベルの距離)、AProp1(「2」の距離)では、AProp2がビジネスロジックよりも優先されます。

  • GreatGrandChildの場合も、AProp1が設定されているため(距離が「0」)、AProp2よりも優先されます(距離が「1」)。

  • 最後に、GreatGreatGrandChildの場合も、AProp1とAProp2の両方が継承によって取得されますが、AProp1は階層(「1」の距離)とAProp2(「2」の距離)の近くに設定されているため、AProp1は使用したいもの。

ソースを見つけることができれば、チェーンを歩いて距離を数えることができます。ソースが必要です。

ノート:

記録としては、はい、両方を同じレベルに設定できます。その場合、AProp2が優先されますが、これはこの質問とは関係ありません。

優先度を上げる方法として同じ値を使用する場合でも、プロパティを再適用することもできます(GreatGrandChildを参照) 。そのため、ソースがどこにあるか/チェックしている要素からどれだけ離れているかを知る必要があります。

4

3 に答える 3

1

非常に興味深い問題です!タイプを格納するDependencyObjectに添付プロパティを追加できます(タイプが適切でない場合はオブジェクト参照を格納できます)。これを使用して、プロパティが設定されたオブジェクトのタイプを記録します。

 public class DependencyPropertyExtension
    {
        public static Type GetAprop1Owner(DependencyObject obj)
        {
            return (Type)obj.GetValue(Aprop1OwnerProperty);
        }

        public static void SetAprop1Owner(DependencyObject obj, Type value)
        {
            obj.SetValue(Aprop1OwnerProperty, value);
        }

        public static readonly DependencyProperty Aprop1OwnerProperty = DependencyProperty.RegisterAttached("Aprop1Owner", typeof(Type), typeof(DependencyProperty), new UIPropertyMetadata(null));
    }

次に、依存関係プロパティAprop1にUIPropertyMetaDataを追加して、更新に応答できるようにします。

public object Aprop1
{
    get { return (object)GetValue(Aprop1Property); }
    set { SetValue(Aprop1Property, value); }
}
public static readonly DependencyProperty Aprop1Property =
    DependencyProperty.Register("Aprop1", typeof(object), typeof(Level1), new UIPropertyMetadata(null, new PropertyChangedCallback( (s, e) =>
        {
            DependencyPropertyExtension.SetAprop1Owner(s, s.GetType());
        })));

ここで行っているのは、アタッチされたプロパティを、プロパティが設定されているオブジェクトのタイプに更新することだけです。

この情報は、次のオブジェクトから読み戻すことができます。

DependencyPropertyExtension.GetAprop1Owner(testObject).FullName
于 2012-06-01T09:21:13.680 に答える
0

私はそれを見つけたと思います。それらの1つ「あなたの目の前でずっと」もの。DependencyPropertyHelper.GetValueSourceこれは、オブジェクトのプロパティ値が継承されているかどうかを判断するために使用することを中心に展開されます。

もちろんそれだけでは十分ではありませんが、そこから簡単に行くことができます。

その知識があれば、問題のオブジェクトを受け取り、両方のプロパティの存在をチェックするメソッドを作成し(デフォルト値、スタイル、テンプレートなどのために「設定」されている可能性があることを忘れないでください)、それに応じて続行します。

  • 2つのうち1つだけが設定されている場合は、それを使用して完了です。必要に応じて処理します。

  • 両方が設定されている場合は、単一のプロパティが使用するのと同じ優先順位を使用します。(つまり、LocalビートInheritInheritビートDefaultなど)2つのプロパティソースの値を同じレベルで相互に比較しているだけです。

  • ソースが同じでそうでないInherit場合は、ビジネスロジックで優先されるソース(この場合はAProp2)を使用します。

  • それらが同じである場合 Inherit、論理ツリー(または必要に応じてビジュアル)を上に移動し、親を渡す同じ関数を再帰的に呼び出します。

もちろん、このプロパティがアニメーションなどの影響を受ける場合、ロジックはもう少し複雑になりますが、この場合、ローカルに設定されるか、継承されます。他にはあまりありません。

私がそれを見ているので、今はかなり単純です。これが他の人に役立つことを願っています!

于 2012-06-01T18:16:16.740 に答える
0

タプルを使用して、両方の値を含めます。最も近い継承されたプロパティには、どちらかの値が含まれ、優先されます。

ビジュアルツリー全体を反映する必要がなくなり、依存関係プロパティの組み込みメカニズムに依存します。

于 2012-06-18T14:36:31.173 に答える