Почему это?
MainWindow.xaml:
<Window x:Class="MVVMProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ContentControl Content="{Binding}"/>
</Grid>
</Window>
Настройте свой ExampleView.xaml как:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
<DataTemplate DataType="{x:Type vms:ExampleVM}" >
<Grid>
<ActualContent/>
</Grid>
</DataTemplate>
</ResourceDictionary>
И создайте такое окно:
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
MainWindow app = new MainWindow();
ExampleVM context = new ExampleVM();
app.DataContext = context;
app.Show();
}
}
Когда это можно сделать так?
App.xaml: (Установить окно запуска / Просмотр)
<Application x:Class="MVVMProject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="ExampleView.xaml">
</Application>
ExampleView.xaml: (Окно, а не ResourceDictionary)
<Window x:Class="MVVMProject.ExampleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
>
<Window.DataContext>
<vms:ExampleVM />
</Window.DataContext>
<Grid>
<ActualContent/>
</Grid>
</Window>
По сути, это «Просмотр как шаблон данных» (VaD) против «Просмотр как окно» (VaW).
Вот мое понимание сравнения:
- VaD: позволяет переключать просмотры, не закрывая окно. (Это нежелательно для моего проекта)
- VaD: VM абсолютно ничего не знает о View, тогда как в VaW он (только) должен иметь возможность создавать его при открытии другого окна.
- VaW: я действительно могу видеть свой xaml, отображаемый в конструкторе (я не могу с VaD, по крайней мере, в моей текущей настройке)
- VaW: Интуитивно работает с открытием и закрытием окон; каждое окно имеет (есть) соответствующий View (и ViewModel)
- VaD: ViewModel может передавать исходную ширину окна, высоту, возможность изменения размера и т. Д. Через свойства (тогда как в VaW они устанавливаются непосредственно в окне)
- VaW: можно установить FocusManager.FocusedElement (не уверен, как в VaD)
- VaW: меньше файлов, так как мои типы окон (например, лента, диалог) включены в их представления.
Так что здесь происходит? Разве я не могу просто создать свои окна в XAML, получить чистый доступ к их данным через свойства виртуальной машины и покончить с этим? Код программной части такой же (практически ноль).
Я изо всех сил пытаюсь понять, почему я должен перетасовать все материалы View в ResourceDictionary.
Ответы:
Люди используют
DataTemplates
этот способ, когда хотят динамически переключать представления в зависимости от ViewModel:<Window> <Window.Resources> <DataTemplate DataType="{x:Type local:VM1}"> <!-- View 1 Here --> </DataTemplate> <DataTemplate DataType="{x:Type local:VM2}"> <!-- View 2 here --> </DataTemplate> </Window.Resources> <ContentPresenter Content="{Binding}"/> </Window>
Так,
если
Window.DataContext
является экземпляромVM1
, тоView1
будет отображаться,и если
Window.DataContext
является экземпляромVM2
, тоView2
будет отображаться.Конечно, это не имеет никакого смысла, если ожидается только 1 просмотр и никогда не менялся.
источник
Поскольку в VaD модели представлений ничего не знают о представлениях, вы можете создать полностью функционирующее приложение, целиком состоящее только из моделей представлений и без представлений. Это приводит к возможности написания приложения, которое может полностью управляться кодом. Это, в свою очередь, дает возможность проводить интеграционное тестирование без графического интерфейса. Интеграционное тестирование через графический интерфейс, как известно, хрупкое, в то время как тестирование через модели представления должно быть более надежным.
источник
Из моего личного опыта: обе рабочие модели доступны, в зависимости от того, что вы хотите, и в зависимости от требований приложения. Идея
VaD
состоит в том, чтобы разобрать содержимое и контейнер. Если вы реализуете,VaD
вы можете использовать этот шаблон (по умолчанию), когда бы вы ни показывали любой элемент этого типа. Вы можете использовать егоItemsControls
(списки, представления списков, сетки и т. Д.) ИContentControls
только для создания привязок. Как вы сказали,VaD
работает для переключения содержимого окна без закрытия и открытия нового. Также вы можете определить представление с помощьюUserControls
, затем вы берете под контроль сфокусированные элементы, а также можете управлять кодом позади. Итак, ваш шаблон данных может быть таким:<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vms="clr-namespace:MVVMProject.ViewModels"> <DataTemplate DataType="{x:Type vms:ExampleVM}" > <CustomUserControl A="{Binding A}" B="{Binding B}" DataContext="{Binding}" .../> </DataTemplate>
Вы также
UserControl
можете установить свойства зависимостей, что упростит работу, поскольку позволяет привязать и разъединять приложение.Но, конечно, если ваше приложение не требует динамического переключения содержимого, его можно использовать
VaW
для главного окна или любого другого окна. Фактически, вы можете использовать обаVaW
иVaD
. Последний можно использовать для внутренних элементов приложения, для которых не нужны окна. Вы выбираете, что лучше для вас, в зависимости от требований приложения и времени, необходимого для разработки приложения. Надеюсь, этот личный опыт поможет ...источник