Я могу установить связь между моделью представления и представлением с помощью следующего синтаксиса DataContext
:
<UserControl.DataContext>
<view_model:MainMenuModel />
</UserControl.DataContext>
И я также могу установить связь между моделью представления и представлением с помощью следующего синтаксиса DataTemplate
:
<DataTemplate
DataType="{x:Type viewModel:UserViewModel}">
<view:UserView />
</DataTemplate>
Какая разница между двумя? Второй XAML не устанавливает контекст данных представления?
2 ответа
Ваш второй 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
- это то, к чему привязан элемент. В основном это тип object
. В шаблоне MVVM это чаще всего объект ViewModel, но это не обязательно. Это просто некоторая контекстная информация, которую вы хотите применить к этому FrameworkElement
. Само по себе это не влияет напрямую на визуальное представление.
Когда WPF хочет отобразить какой-либо объект, который не имеет собственного визуального представления (например, не является потомком UIElement
, он будет искать, существует ли соответствующий DataTemplate
, чтобы определить, как он должен представлять это В вашем примере вы сказали, что класс UserViewModel
должен быть представлен с помощью элемента управления UserView
, но вы фактически не создали ни UserViewModel
, ни UserView
.
Эти два понятия часто идут вместе. Например, представьте, что у вас есть ObservableCollection<object>
, в котором есть объект Foo
и Bar
. Вы можете определить разные DataTemplate
для Foo
и Bar
. Затем вы можете привязать свою коллекцию к ItemsControl
. Каждый объект в элементе управления получит визуальное представление на основе соответствующего DataTemplate
его типа.
Другой простой пример: если у вас есть свойство в вашей ViewModel с именем DisplayObject
и вы просто хотите, чтобы оно отображалось с любым DataTemplate
, которое вы определили, вы можете использовать элемент управления ContentPresenter
:
<ContentPresenter DataContext="{Binding DisplayObject}"/>
Опять же, это приводит к тому, что WPF ищет правильный шаблон для типа и использует его для создания представления.
Похожие вопросы
Связанные вопросы
Новые вопросы
wpf
Windows Presentation Foundation, или WPF, является подсистемой для визуализации пользовательских интерфейсов в приложениях на основе Windows.