WPF中的DataTemplate和DataContext有什么区别?

时间:2010-03-09 09:34:11

标签: wpf wpf-controls binding

我可以通过以下DataContext语法设置View Model和view之间的关系:

 <UserControl.DataContext>
    <view_model:MainMenuModel />
</UserControl.DataContext>

我还可以通过以下DataTemplate语法设置View Model和view之间的关系:

    <DataTemplate
        DataType="{x:Type viewModel:UserViewModel}">
        <view:UserView />
    </DataTemplate>

两者有什么区别?第二个XAML是否未设置视图的数据上下文?

2 个答案:

答案 0 :(得分:8)

您的第二个XAML定义了一个模板,可用于显示viewModel:UserViewModel类型的对象。它不会为任何内容设置数据,但如果要求ContentPresenter显示该类型的对象,它将使用您的模板。

您的第一个XAML正在设置控件的DataContext属性。它定义您在该范围内执行的任何绑定都将使用DataContext作为绑定的根(除非明确覆盖)。有关DataContext工作的简单示例,请比较这两个(都假设“s”是System命名空间):

<StackPanel>  
  <TextBlock Text="{Binding Day, Source={x:Static s:DateTime.Now}}" />
  <TextBlock Text="{Binding Month, Source={x:Static s:DateTime.Now}}" />
  <TextBlock Text="{Binding Year, Source={x:Static s:DateTime.Now}}" />
</StackPanel>

<StackPanel DataContext="{Binding Source={x:Static s:DateTime.Now}}">  
  <TextBlock Text="{Binding Day}" />
  <TextBlock Text="{Binding Month}" />
  <TextBlock Text="{Binding Year}" />
</StackPanel>

两个StackPanels将呈现相同的内容,但第二个更容易重用。 (例如:如果你想显示不同的日期,你只需要在一个地方更改装订。)

答案 1 :(得分:2)

DataContext的{​​{1}}是元素绑定的内容。它基本上是FrameworkElement类型。在MVVM模式中,这通常是ViewModel对象,但它不一定是。它只是您想要应用于object的一些上下文信息。它本身并不直接影响视觉表现。

当WPF想要显示一些没有自己的可视化表示的对象时(例如,不是FrameworkElement的后代),它会查看是否存在相应的UIElement来定义它应该显示该数据。在您的示例中,您已说过应使用DataTemplate控件显示UserViewModel类,但您实际上并未创建UserView或{{1} }。

这两个概念经常在一起。例如,假设您有一个UserViewModel,其中包含UserViewObservableCollection<object>个对象。您可以为FooBar定义不同的DataTemplate。然后,您可以将您的集合绑定到Foo。控件中的每个对象都将根据其类型中的相应Bar获得可视化表示。

另一个简单示例:如果您的ViewModel上有一个名为ItemsControl的属性,并且您只希望它与您定义的DataTemplate一起显示,则可以使用DisplayObject控件:

DataTemplate

同样,这会导致WPF查找该类型的正确模板,并使用它来构造表示。

相关问题