【问题标题】:What is the difference between DataTemplate and DataContext in WPF?WPF中的DataTemplate和DataContext有什么区别?
【发布时间】:2011-01-25 08:39:45
【问题描述】:

我可以通过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没有设置视图的数据上下文吗?

【问题讨论】:

    标签: wpf wpf-controls binding


    【解决方案1】:

    您的第二个 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 的渲染效果相同,但第二个更容易重用。 (例如:如果您想显示不同的日期,您只需在一处更改绑定即可。)

    【讨论】:

    • 嗨彼得,本感谢大家的回复。我想知道是否可以将控件的 datacontext 和 datatemplate 设置为相同的视图模型?
    • @Ashish:您可以将 DataContext 设置为 ViewModel 本身,但您将 DataTemplate 设置为 显示 ViewModel 的模板 - 而不是 ViewModel 本身。
    【解决方案2】:

    FrameworkElementDataContext 是元素绑定的对象。它基本上属于object 类型。在 MVVM 模式中,这是最常见的 ViewModel 对象,但并非必须如此。它只是您想要应用于FrameworkElement 的一些上下文信息。它本身并不直接影响视觉表现。

    当 WPF 想要显示一些没有它自己的可视化表示的对象时(例如不是从 UIElement 继承的,它会查看是否存在相应的 DataTemplate 来定义它应该如何呈现该数据. 在您的示例中,您说过应该使用UserView 控件来呈现UserViewModel 类,但您实际上并没有创建UserViewModelUserView

    这两个概念经常结合在一起。例如,假设您有一个ObservableCollection&lt;object&gt;,其中包含一个Foo 和一个Bar 对象。您可以为FooBar 定义不同的DataTemplates。然后您可以将您的收藏绑定到ItemsControl。控件中的每个对象都将根据其类型中的适当DataTemplate 获得视觉表示。

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

    <ContentPresenter DataContext="{Binding DisplayObject}"/>
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-19
      • 1970-01-01
      • 1970-01-01
      • 2014-03-13
      • 2010-11-23
      • 2012-09-04
      • 1970-01-01
      • 2012-12-19
      相关资源
      最近更新 更多