49

わかりました...これで頭をかいてしまいます。2つのWPFコントロールがあります。1つはユーザーコントロールで、もう1つはカスタムコントロールです。それらをUserFooとCustomFooと呼びましょう。CustomFooのコントロールテンプレートでは、名前付きパーツであるUserFooのインスタンスを使用して、テンプレートの適用後にアクセスできるようにします。それはうまくいきます。

これで、UserFooとCustomFooの両方に、Textこのように宣言されたプロパティが定義されます(独立して、つまり、AddOwnerを使用する共有DPではありません。質問しないでください...)。

public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    "Text",
    typeof(string),
    typeof(UserFoo), // The other is CustomFoo
    new FrameworkPropertyMetadata(
        null,
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
        null,
        null,
        true,
        UpdateSourceTrigger.PropertyChanged
    )
);

特に、モードがTwoWayに設定され、UpdateSourceTriggerがPropertyChangedに設定されていることに注意してください。

そのため、CustomFooのスタイルテンプレートで、CustomFooのTextプロパティをソースとして内部のUserFooのTextプロパティにバインドしたいと思います。通常、これは簡単です。UserFooのtextプロパティを"{TemplateBindingText}"に設定しただけですが、何らかの理由で一方向にしか進まない(つまり、UserFooはCustomFooから適切に設定されていますが、逆ではありません)。ただし、両方のDPが双方向に設定されています。ただし、テンプレートバインディングの代わりに相対ソースバインディングを使用する場合は、うまく機能します。えっと…なに?

// This one works
Text="{Binding Text, RelativeSource={RelativeSource AncestorType={local:CustomFoo}}, Mode=TwoWay}"

// As does this too...
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"

// But not this one!
Text="{TemplateBinding Text}"

では、何が得られるのでしょうか?私は何が欠けていますか?

4

2 に答える 2

71

MSDN でこのフォーラムの投稿を見つけました: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0bb3858c-30d6-4c3d-93bd-35ad0bb36bb4/

それはこう言います:

TemplateBinding は、テンプレート シナリオ用に最適化された形式の Binding であり、次で構築された Binding に似ています。

{Binding RelativeSource={RelativeSource TemplatedParent}}

OPからのメモ:ドキュメントに記載されていることに反して、実際にはこれである必要があります...

{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}

ドキュメントに対して苦情を申し立てたところ、常に一方向であるという文が追加されましたが、コード例にはまだモードがリストされていませんが、何もないよりはましだと思います.)

TemplateBinding は、テンプレート化された親からテンプレート バインドされたプロパティにデータを転送します。反対方向または双方向にデータを転送する必要がある場合は、Mode プロパティを OneWayToSource または TwoWay に設定して、TemplatedParent の RelativeSource で Binding を作成します。

詳細: http://msdn.microsoft.com/en-us/library/ms742882.aspx

Mode=OneWayは、TemplateBinding を使用する「最適化」の 1 つであるように見えます。

于 2011-05-06T15:06:42.013 に答える
11

TemplateBinding は双方向バインディングをサポートしていません。Binding だけがサポートしています。BindsTwoWayBeDefault オプションを使用しても、双方向バインディングはサポートされません。

詳細については、こちらを参照してください。要約すると、次のようになります。

ただし、TemplateBinding は、テンプレート化された親から TemplateBinding を持つ要素への、一方向にのみデータを転送できます。逆方向または双方向にデータを転送する必要がある場合は、RelativeSource が TemplatedParent の Binding が唯一のオプションです。たとえば、双方向バインディングを使用する場合、テンプレート内の TextBox または Slider との対話は、テンプレート化された親のプロパティのみを変更します。

于 2011-05-06T15:07:15.720 に答える