2009-11-27 96 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设计器支持。