2009-07-15 125 views
153

是什麼這2個綁定的區別WPF TemplateBinding VS的RelativeSource TemplatedParent

​​

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

+15

如果你需要雙向綁定,你必須使用第二個選項 –

回答

195

TemplateBinding並不完全相同。 MSDN文檔通常由必須測試軟件功能的單音節SDE的人編寫,因此細微差別不太正確。

TemplateBindings在編譯時根據控件模板中指定的類型進行評估。這允許編譯模板更快地實例化。只需在模板綁定中摸索名稱,就會看到編譯器會標記它。

綁定標記在運行時解析。雖然執行速度較慢,但​​該綁定將解析在模板聲明的類型上不可見的屬性名稱。由於速度較慢,我將指出它的相對性,因爲綁定操作只佔應用程序CPU的很少部分。如果你正在高速爆炸控制模板,你可能會注意到它。

作爲實踐的問題,使用TemplateBinding時,你可以但不要害怕綁定。

+17

所以主要考慮要記住:編譯時間與運行時間。如果您在運行時嘗試更改TemplateBinding,它將不起作用。對 ? –

+2

另請注意,使用Binding代替TemplateBinding可能會影響您在Design Time期間看到的內容。在某些配置中,使用{Binding RelativeSource ...}綁定的屬性不會出現在設計器中(雖然它們在運行時仍會顯示),但如果切換到使用{TemplateBinding ...},則會評估這些屬性在設計時間。 – lfalin

15

TemplateBinding是與TemplatedParent綁定的簡寫,但它不公開Binding類的所有功能,例如,你不能從TemplateBinding控制Binding.Mode。

1

我認爲TemplateBinding不支持Freezable類型(其中包括畫筆對象)。解決問題。可以使用TemplatedParent

18

還有一件事 - TemplateBindings不允許值轉換。他們不允許你傳遞一個轉換器,並且不會自動將int轉換爲字符串,例如(這對Binding來說是正常的)。

+1

謝謝米羅斯拉夫,這是我遇到的問題,切換到使用TemplatedParent解決了這個問題。 – MikeKulls

27

TemplateBinding - 超過使用常規綁定

  • 比均有約束力,但具有較少的功能
  • 只適用一個控件模板的可視化樹內更有效地限制
  • 不能與性質上工作Freezables
  • 在ControlTemplate的觸發器中不起作用
  • 在settin中提供快捷方式g屬性(而不是冗長),例如。{TemplateBinding targetProperty}

定期Binding - 不具有上述TemplateBinding的侷限性

  • 尊重父屬性
  • 復位目標值清除任何明確設置值
  • 例子:< Ellipse Fill =「{Binding RelativeSource = {RelativeSource TemplatedParent},Path = Background}」/ >
2

的RelativeSource TemplatedParent

此模式使一個給定的ControlTemplate屬性綁定到所述的ControlTemplate被施加到控制的一個屬性。爲了最大限度地瞭解這裏的問題是,波紋管

<Window.Resources> 
    <ControlTemplate x:Key="template"> 
     <Canvas> 
      <Canvas.RenderTransform> 
       <RotateTransform Angle="20"/> 
      </Canvas.RenderTransform> 
      <Ellipse Height="100" Width="150" 
        Fill="{Binding 
       RelativeSource={RelativeSource TemplatedParent}, 
       Path=Background}"> 

      </Ellipse> 
      <ContentPresenter Margin="35" 
         Content="{Binding RelativeSource={RelativeSource 
         TemplatedParent},Path=Content}"/> 
     </Canvas> 
    </ControlTemplate> 
</Window.Resources> 

<Canvas Name="Parent0"> 
    <Button Margin="50" 
       Template="{StaticResource template}" Height="0" 
       Canvas.Left="0" Canvas.Top="0" Width="0"> 
     <TextBlock FontSize="22">Click me</TextBlock> 
    </Button> 
</Canvas> 

如果我想在一個給定的控件的屬性適用於它的控制模板,然後我就可以使用TemplatedParent模式的例子。還有一個與TemplateBinding相似的標記擴展,它是第一種簡寫形式,但是TemplateBinding是在編譯時在TemplatedParent的對比度下進行評估的,TemplatedParent是在第一次運行時間之後進行評估的。正如你可以在下圖中所說的那樣,背景和內容從按鈕內部被應用到控制模板。