WPF,UserControl或DataTemplate

时间:2009-11-27 09:29:03

标签: wpf user-controls datatemplate

最近我试图在我的应用程序中重用一些UI元素。当我开始使用WPF编程时,我被告知DataTemplate是重用UI元素的最佳方式。您可以为数据实体定义模板并在任何地方使用它。听起来很不错。 但是,我也发现了一些缺点,特别是在与UserControl进行比较时。

  1. 您无法重用在另一个Window或UserControl中定义的DataTemplate。例如,如果在WindowA.xaml中定义了UserDataTemplate,则无法在WindowB.xaml中使用它。解决方案可能是将DataTemplate作为资源放在全局资源字典中。
  2. DataTemplate很难有一些代码。如第1项所述,如果将DataTemplate放在ResourceDictionary中,则默认情况下无法放置代码。我搜索了问题,是的,我找到了一个让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...;
            }
    }
    
  4. 结果将是:User1将只有一个实例,但是,一旦应用DataTemplate,将创建User2实例,这意味着如果多次应用datatemplate,User2将有许多实例。 但是,与UserControl不同,字段“mousePos”不会有很多副本。如果DataTemplate被应用了100次,则mousePos将不会有100个副本,这意味着100个网格将同时使用唯一的一个mousePos字段,这可能会导致问题。 在UserControl中,您定义的字段仅由控件使用。 100个UserControl实例将有100个字段副本。

    也许我正在以错误的方式使用DataTemplate。任何评论都表示赞赏。

    致以最诚挚的问候,

    扎克

3 个答案:

答案 0 :(得分:27)

从概念上讲,DataTemplates和UserControl解决了两个不同的问题。它们并不是真正可以互换的,所以你的比较并不准确。

DataTemplates是关于将视觉样式应用于DataType的。通常这意味着我有自己的.NET类叫做Foo,我想给它一个视觉风格。我会通过创建一个DataType为Foo的DataTemplate来实现这一点。

然后我可以将这个DataTemplate放在我的应用程序中(例如在App.XAML中),我将视觉样式应用于我的数据对象Foo,无论它在何处使用。通常这意味着您将看到ContentControl,其Content属性绑定到Foo类型的属性。

另一方面的UserControls都是关于XAML的组织。用户控件有助于组织您希望在整个应用程序中重用的XAML块,这些块具有与之关联的行为和功能。这不仅仅是DataTempate的功能。

DataTemplate绑定到一个DataType并显示该类型的视觉效果。 UserControl可以由多个DataType组成,并且可以包含自定义行为。

话虽如此,我很少发现需要UserControl。我使用DataTemplates来模拟我的数据并通过数据绑定和MVVM模式实现我的行为。

答案 1 :(得分:11)

就个人而言,我创建一个UserControl,然后从中创建一个DataTemplate。这对我有好处:

  1. 只能通过重新定义DataTemplate部件来跨窗口使用。
  2. 可以使用代码隐藏(我知道,我知道,但有些事情使用代码隐藏更容易,我不认为基于教条不必要地使我的代码复杂化。)
  3. XAML设计师支持。

答案 2 :(得分:2)

关于2.

我会说DataTemplates不是设计用于代码隐藏的。大多数情况下,您只能使用DataBinding和Commands来连接模型及其表示之间的逻辑。没有代码隐藏也有助于您的应用程序的单元测试。