Я могу установить отношения между Моделью Представления и просмотреть через следующее DataContext
синтаксис:
И я могу также установить отношения между Моделью Представления и просмотреть через следующее DataTemplate
синтаксис:
Каково различие между двумя? Разве второй XAML не устанавливает контекст данных представления?
Ваш второй 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
FrameworkElement
- это то, к чему привязан элемент. В основном это объект типа
. В шаблоне MVVM это чаще всего объект ViewModel, но это не обязательно. Это просто некоторая контекстная информация, которую вы хотите применить к этому FrameworkElement
. Само по себе это не влияет напрямую на визуальное представление.
Когда WPF хочет отобразить какой-либо объект, не имеющий собственного визуального представления (например, не наследник UIElement
, он будет проверять, существует ли соответствующий DataTemplate
чтобы определить, как он должен представлять эти данные. В вашем примере вы сказали, что класс UserViewModel
должен быть представлен с использованием элемента управления UserView
, но вы фактически не создали ни ] UserViewModel
или UserView
.
Эти две концепции часто идут вместе. Например, представьте, что у вас есть ObservableCollection
, в котором есть Foo
и объект Bar
. Вы можете определить разные DataTemplate
s для Foo
и Bar
. Затем вы можете привязать свою коллекцию к an ItemsControl
.Каждый объект в элементе управления получит визуальное представление на основе соответствующего DataTemplate
своего типа.
Другой простой пример: если у вас есть свойство в вашей модели просмотра с именем DisplayObject
, и вы просто хотите, чтобы оно отображалось с любым DataTemplate
, который вы определили, вы можете использовать ContentPresenter
control:
<ContentPresenter DataContext="{Binding DisplayObject}"/>
Опять же, это приводит к тому, что WPF ищет правильный шаблон для типа и использует его для создания представления.