WPF TemplateBindingとRelativeSource TemplatedParent


169

これらの2つのバインディングの違いは何ですか?

<ControlTemplate TargetType="{x:Type Button}">
   <Border BorderBrush="{TemplateBinding Property=Background}">
      <ContentPresenter />
   </Border>
</ControlTemplate>

そして

<ControlTemplate TargetType="{x:Type Button}">
   <Border BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}">
      <ContentPresenter />
   </Border>
</ControlTemplate>


17
TwoWayバインディングが必要な場合は、2番目のオプションを使用する必要があります
Joachim Kerschbaumer '23

回答:


207

TemplateBindingはまったく同じではありません。MSDNのドキュメントは、ソフトウェア機能について単音節のSDEをクイズする必要がある人々によって書かれることが多いため、ニュアンスが正しくありません。

TemplateBindingsは、コントロールテンプレートで指定されたタイプに対してコンパイル時に評価されます。これにより、コンパイルされたテンプレートをはるかに高速にインスタンス化できます。テンプレートバインディングで名前をいじるだけで、コンパイラがフラグを付けることがわかります。

バインディングマークアップは実行時に解決されます。バインディングの実行は遅くなりますが、テンプレートによって宣言されたタイプでは表示されないプロパティ名が解決されます。遅くなりますが、バインディング操作がアプリケーションのCPUをほとんど使用しないため、この種の相対であることを指摘しておきます。コントロールテンプレートを高速でブラストしている場合は、それに気付くでしょう。

実際には、Bindingを恐れることはできるが恐れない場合は、TemplateBindingを使用します。


18
したがって、覚えておくべき主なことは、コンパイル時間とランタイムです。ランタイム中に変更しようとすると、TemplateBindingは機能しません。正しい ?
PaN1C_Showt1Me 2010

3
また、TemplateBindingの代わりにBindingを使用すると、設計時に表示される内容に影響を与える可能性があることに注意してください。特定の構成では、{Binding RelativeSource ...}を使用してバインドされているプロパティはデザイナーに表示されません(ただし、実行時には表示されます)が、{TemplateBinding ...}を使用するように切り替えると、これらのプロパティが評価されます設計時。
lfalin 2014年

今後の訪問者に役立つ場合に備えて1つ追加しておきますが、TemplateBindingはコンパイル時に評価されるため、TemplateBindingを使用してユーザー定義の添付プロパティにバインドすることはできません。ユーザー定義の添付プロパティの場合、「{Binding RelativeSource = {RelativeSource TemplatedParent} ...}」を使用する必要があります
MNB

35

TemplateBinding-通常のバインディングを使用するよりも制限が多い

  • バインディングよりも効率的ですが、機能が少なくなります
  • ControlTemplateのビジュアルツリー内でのみ機能します
  • Freezablesのプロパティでは機能しません
  • ControlTemplateのトリガー内では機能しません
  • プロパティを設定するためのショートカットを提供します(詳細ではありません)。例:{TemplateBinding targetProperty}

通常のバインド-TemplateBindingの上記の制限はありません

  • 親プロパティを尊重
  • ターゲット値をリセットして、明示的に設定された値をすべてクリアします
  • 例:<Ellipse Fill = "{Binding RelativeSource = {RelativeSource TemplatedParent}、Path = Background}" />

22

もう1つ-TemplateBindingsは値の変換を許可しません。それらはあなたにコンバーターを渡すことを許可せず、例えばintを例えば文字列に自動的に変換しません(これはバインディングの通常のことです)。


1
Miroslav氏に感謝します。これは私が遭遇した問題でした。TemplatedParentを使用するように切り替えると問題が解決しました。
MikeKulls

17

TemplateBindingは、TemplatedParentを使用したバインドの省略表現ですが、Bindingクラスのすべての機能を公開しているわけではありません。たとえば、TemplateBindingからBinding.Modeを制御することはできません。


1

TemplateBindingはFreezable型(ブラシオブジェクトを含む)をサポートしていないと思いました。問題を回避するため。TemplatedParentを利用できます


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.