[英]What is the difference between DataTemplate and DataContext in WPF?
I can set the relationship between View Model and view through following DataContext
syntax: 我可以通过以下DataContext
语法设置View Model和view之间的关系:
<UserControl.DataContext>
<view_model:MainMenuModel />
</UserControl.DataContext>
And I can also set the relationship between View Model and view through following DataTemplate
syntax: 我还可以通过以下DataTemplate
语法设置View Model和view之间的关系:
<DataTemplate
DataType="{x:Type viewModel:UserViewModel}">
<view:UserView />
</DataTemplate>
What is the difference between the two? 两者有什么区别? Is the second XAML not setting the data context of a view? 第二个XAML是否未设置视图的数据上下文?
Your second XAML defines a template that can be used to display an object of type viewModel:UserViewModel
. 您的第二个XAML定义了一个模板 ,可用于显示viewModel:UserViewModel
类型的对象viewModel:UserViewModel
。 It doesn't set data for anything but, if a ContentPresenter
is asked to display an object of that type, it will use your template. 它不会为任何内容设置数据,但如果要求ContentPresenter
显示该类型的对象,它将使用您的模板。
Your first XAML is setting the DataContext
property of your control. 您的第一个XAML正在设置控件的DataContext
属性。 It defines that any bindings you perform within that scope will use the DataContext
as the root of the binding (unless explicitly overriden). 它定义您在该范围内执行的任何绑定都将使用DataContext
作为绑定的根(除非明确覆盖)。 For a simple example of DataContext
at work, compare these two (both assume that "s" is the System
namespace): 有关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>
Both StackPanels
will render identically, but the second is more easily reused. 两个StackPanels
都会以相同的方式呈现,但第二个更容易重用。 (Eg: you only have to change the binding in one place if you wanted to display a different date.) (例如:如果要显示不同的日期,则只需在一个地方更改绑定。)
The DataContext
of a FrameworkElement
is what the element is bound to. FrameworkElement
的DataContext
是元素绑定的内容。 It is fundamentally of type object
. 它基本上是类型object
。 In the MVVM pattern, this is most frequently the ViewModel object, but it need not be. 在MVVM模式中,这通常是ViewModel对象,但它不一定是。 It is simply some context information you want to apply to that FrameworkElement
. 它只是您要应用于FrameworkElement
一些上下文信息。 It does not directly affect the visual representation, by itself. 它本身并不直接影响视觉表示。
When WPF wants to display some object that doesn't have it's own visual representation (eg isn't descended from UIElement
, it will look to see if a corresponding DataTemplate
exists to define how it should present that data. In your example, you have said that the UserViewModel
class should be presented using the UserView
control, but you have not actually created either the UserViewModel
or UserView
. 当WPF想要显示一些没有自己的可视化表示的对象时(例如,不是来自UIElement
,它会查看是否存在相应的DataTemplate
来定义它应该如何呈现该数据。在你的例子中,你有表示应该使用UserView
控件呈现UserViewModel
类,但是您实际上没有创建UserViewModel
或UserView
。
These two concepts often go together. 这两个概念经常在一起。 For example, imagine you had an ObservableCollection<object>
which had in it a Foo
and a Bar
object. 例如,假设您有一个ObservableCollection<object>
,其中包含一个Foo
和一个Bar
对象。 You could define different DataTemplate
s for Foo
and Bar
. 您可以为Foo
和Bar
定义不同的DataTemplate
。 Then you could bind your collection into an ItemsControl
. 然后,您可以将您的集合绑定到ItemsControl
。 Each object in the control would get a visual representation based on the appropriate DataTemplate
from its type. 控件中的每个对象都将根据其类型中的相应DataTemplate
获得可视化表示。
Another simple example: if you have a property on your ViewModel named DisplayObject
and you simply want it to appear with whatever DataTemplate
you have defined, you can use the ContentPresenter
control: 另一个简单示例:如果ViewModel上有一个名为DisplayObject
的属性,并且您只希望它与您定义的任何DataTemplate
一起出现,则可以使用ContentPresenter
控件:
<ContentPresenter DataContext="{Binding DisplayObject}"/>
Again, this results in WPF looking up the correct Template for the type and using that to construct a representation. 同样,这会导致WPF查找该类型的正确模板并使用它来构造表示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.