2009-11-27 145 views
20

最近我試圖在我的應用程序中重用一些UI元素。當我開始使用WPF編程時,我被告知DataTemplate是重用UI元素的最佳方式。您可以爲您的數據實體定義一個模板,並在任何地方使用它。聽起來很不錯。 但是,我還發現一些缺點,尤其是與UserControl進行比較時。WPF,UserControl或DataTemplate

  1. 您不能重用在另一個Window或UserControl中定義的DataTemplate。例如,如果UserDataTemplate在WindowA.xaml中定義,則不能在WindowB.xaml中使用它。解決方案可能是將DataTemplate作爲全局資源字典中的資源。
  2. DataTemplate很難有一些代碼。如第1項所述,如果將DataTemplate放入ResourceDictionary中,則默認情況下沒有地方放置代碼。我GOOGLE了這個問題,是的,我發現一個技巧,使ResourceDictionary有一個cs文件。但它仍然有另一個問題。
  3. DataTemplate中的另一個問題是,你必須與DataTemplate中自身的實例和DataTemplate中的內容的實例之間的差別清晰。一個DataTemplate將只有一個「DataTemplate實例」,並且可能有許多DataTemplate內容的實例。讓我舉個例子來說吧:

    <DataTemplate> 
         <DataTemplate.Resources> 
           <my:User x:key="User1"/> 
         </DataTemplate.Resources>     
         <Grid MouseLeftButtonDown="OnMouseLeftButtonDown"> 
           <Grid.Resources> 
             <my:User x:key="User2"/> 
           </Grid.Resources> 
         </Grid>   
    </DataTemplate> 
    
    
    public partial class CodeBehind 
    { 
         Point mousePos = new Point(); 
    
         private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
         { 
           mousePos = e.Pos...; 
         } 
    } 
    

的結果將是:用戶1只會有一個實例,但是,用戶2實例將一旦施加的DataTemplate,這意味着用戶2將創建很多情況下,如果多次應用數據模板。 但是,與UserControl不同,「mousePos」字段不會有多個副本。如果DataTemplate應用了100次,mousePos將不會有100個副本,這意味着100個網格將同時使用唯一的一個mousePos字段,這可能會導致問題。 在UserControl中,您定義的字段只能由控件使用。 100個UserControl實例將有100個字段副本。

也許我在錯誤的道路使用的DataTemplate。任何意見表示讚賞。

最好的問候,

扎克

回答

25

概念的DataTemplates和用戶控件解決兩個不同的問題。它們不是真正可以互換的,所以你的比較不是很準確。

DataTemplates都是關於將視覺樣式應用於DataType的。通常這意味着我有我自己的.NET類,稱爲Foo,我想給它一個視覺風格。我會通過創建一個DataType爲Foo的DataTemplate來做到這一點。

然後我就可以把這個DataTemplate中在我的應用程序(在App.xaml中說),我將應用到我的數據對象美孚我的視覺風格無論在何處使用。通常這意味着您將看到ContentControl具有綁定到Foo類型屬性的Content屬性。

另一方面,用戶控件都是關於XAML的組織。用戶控件可幫助組織XAML的塊,您希望在整個應用程序中重複使用具有與其相關的行爲和功能的XAML塊。這不僅僅是DataTempate的功能。

DataTemplate綁定到一個DataType並顯示該類型的可視化。用戶控件可以由多個數據類型組成,並可以包含自定義行爲。

話雖這麼說,我很少找到一個用戶控件的需要。我使用DataTemplates遍歷數據模型,並通過數據綁定和MVVM模式實現我的行爲。

2

約2

我想說的DataTemplates不是設計與代碼隱藏中使用。大多數情況下,只能使用DataBinding和Commands來連接模型與其表示之間的邏輯。沒有代碼隱藏也有助於你的應用程序的單元測試。

10

就個人而言,我創建了一個用戶控件,然後進行從一個DataTemplate。這對我來說有以下好處:

  1. 只能通過重新定義DataTemplate部分才能跨窗口使用。
  2. 可以使用代碼隱藏(我知道,我知道,但有些東西用代碼隱藏只是就輕鬆多了,我不明白這一點不必要的複雜化基礎上的教條我的代碼)。
  3. XAML設計器支持。