Подтвердить что ты не робот

WPF MVVM Зачем использовать ContentControl + DataTemplate Views, а не прямые XAML Window Views?

У меня вопрос о MVVM в WPF, который меня заводит.

Зачем делать следующее:?

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: (Установить начальное окно /View )

<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: (a Window not a 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>

По существу это "Просмотр как DataTemplate" (VaD) и "Просмотр как окно" (VaW)

Вот мое понимание сравнения: (Примечание: я использую VS 2008, поэтому мне не хватает Blendability &/или другого материала)

  • VaD: позволяет переключать виды, не закрывая окно. (Это нежелательно для моего проекта)
  • VaD: VM ничего не знает о представлении, тогда как в VaW он (только) должен иметь возможность создавать экземпляр при открытии другого окна
  • VaW: Я действительно вижу, что мой xaml отображается в Дизайнере (я не могу с VaD, по крайней мере, в моей текущей настройке)
  • VaW: работает интуитивно с открытие и закрытие окон; каждое окно имеет (есть) соответствующий вид (и ViewModel)
  • VaD: ViewModel может передавать начальную ширину окна, высоту, изменяемость и т.д. через свойства (тогда как в VaW они непосредственно устанавливаются в окне)
  • VaW: Можно установить FocusManager.FocusedElement(не уверен, как в VaD)
  • VaW: Меньше файлов, так как мои типы окон (например, Ribbon, Dialog) включены в их представления

Итак, что здесь происходит? Не могу ли я просто создать свои окна в XAML, получить доступ к их данным по свойствам виртуальной машины и сделать с ними? Кодировка - то же самое (фактически ноль). Я пытаюсь понять, почему я должен перетасовать все материалы View в ResourceDictionary. (Но я не хочу делать это неправильно;-))


Это даже имеет значение? Есть что-то, что я пропустил? Большое спасибо за чтение.: О


Спасибо Рейчел Лим и Ник Поляк за мое расцветное понимание MVVM

Изменить: незначительное изменение потока

4b9b3361

Ответ 1

Люди используют DataTemplates таким образом, когда они хотят динамически переключать Views в зависимости от 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 вид и никогда не менялся.

Надеюсь, это достаточно ясно: P

Ответ 2

Так как в VaD модели представления ничего не знают о представлениях, вы можете создать полностью функционирующее приложение, полностью состоящее только из моделей просмотра и без представлений. Это приводит к возможности написания приложения, которое может полностью управляться кодом. Это, в свою очередь, приводит к возможности проведения интеграционного тестирования без GUI. Интеграционное тестирование через графический интерфейс, как известно, является хрупким - в то время как тестирование через модели просмотра должно быть более надежным.

Ответ 3

Из моего личного опыта: Обе рабочие модели являются aviables, в зависимости от того, что вы хотите, и в зависимости от требований приложения. Идея 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. Этот последний можно использовать для внутренних элементов приложения, для которых не требуются окна. Вы улучшаете то, что лучше для вас, в зависимости от требований приложения и времени, которое можно найти при разработке приложения. Надеюсь, что этот личный опыт поможет...