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

Как указать тип DataContext (ViewModel), чтобы получить проверку привязки времени разработки в редакторе XAML без создания объекта ViewModel?

Я могу указать DataContext следующим образом:

<Window ... >
    <Window.DataContext>
        <MainViewModel />
    </Window.DataContext>
    ...
</Window>

И в этом случае WPF создаст объект типа MainViewModel и присвоит его свойству DataContext окна (это происходит внутри метода Window InitializeComponent()).

Но что, если мой ViewModel не имеет конструктора по умолчанию. Или что, если я хочу инициализировать ViewModel и назначить его DataContext после выполнения Window.InitializeComponent() (внутри конструктора Window или из того же кода, который создает экземпляр окна) - в этом случае WPF создает ViewModel (внутри InitializeComponent()), назначает его к окну DataContext, а затем я перезаписываю его другим экземпляром ViewModel (я беспокоюсь о ненужном экземпляре объекта здесь).

Я хотел бы иметь возможность указать только тип ViewModel, поэтому я бы получил предупреждение о времени разработки, если я пропустил имя свойства внутри {Binding} (или после переименования свойства), или я мог бы перейти к Объявление, нажав (в XAML) на имя свойства внутри {Binding PropertyName}.

Спасибо за ваше бесценное время.

4b9b3361

Ответ 1

Это сложная часть, если вы делаете самостоятельный MVVM.

Ваши варианты, в основном:

Использовать инъекцию зависимостей

Вы можете ввести ViewModel в свой конструктор Page/Window и назначить его внутри него.

У этого есть несколько недостатков.

  • сложнее использовать модели времени разработки
  • Мнения не могут быть созданы с XAML больше

ViewModel Сначала с помощью службы навигации

Вы разрешите свои ViewModels и сделаете всю свою навигацию через навигационную службу. В ViewModels вы передаете a INavigationService. Вы можете перейти к представлению с помощью типа ViewModel. Внутри он создает экземпляр ViewModel через Injection Dependency Injection, а затем создает экземпляр представления (на основе соглашений об именах или конфигурации DI)

Это немного лучше, но все равно не позволит вам создавать экземпляры в XAML. Большой плюс - это позволяет вам легко передавать параметры в ViewModel (имея свойство ViewModels реализовать свойство INavigationAware с помощью метода NavigatedTo, который вызывается после создания экземпляра и передает параметр)

ViewModelLocator/Прикрепленное свойство/поведение

С помощью этого вы создадите прикрепленное свойство, которое вы либо установите на true (то есть autowire), либо на тип ViewModel (чтобы больше контролировать экземпляр ViewModel), а также найти и разрешить ViewModel и назначить Это.

В основном он дает все преимущества выше плюс форма представления формы View.

В последнем случае Microsoft MVVM-инфраструктура "Prism" (служба навигации navigationService.Navigate("MyPage", myParameterForViewModel), создание и назначение DataContext из XAML через autowireing (в XAML: prism:ViewModelLocator.AutoWireViewModel="True").

Как говорится, лучше использовать зрелую MVVM Framework, которая выполняет эти части вашей проводки (даже если вы решите не использовать базовые классы, такие как BindableBase или что-то, что оно вызвало в указанной структуре).

Что касается времени разработки ViewModel/автоматического завершения для ViewModels:

Для этого вы можете использовать атрибуты Blend Design-Time. Сначала нужно добавить ссылки на сборку Blend. Затем вы можете добавить пространство имен xmlns:d="http://schemas.microsoft.com/expression/blend/2008" в свою страницу/представление.

Затем вы можете привязать его к своей странице через d:DataContext="{d:DesignInstance my:DesignTimeViewModel, IsDesignTimeCreatable=True}. Обратите внимание на d: перед DataContext, это важно. Этот DataContext будет использоваться только в Дизайнере (Visual Studio XAML Designer или в Blend). Это делается для предотвращения вмешательства в нормальный DataContext (без префикса).

Пример:

<Window x:Class="WpfApplication1.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:myApp="clr-namespace:WpfApplication1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance myApp:Window2ViewModel, IsDesignTimeCreatable=True}">
    <Grid>
        <TextBlock Text ="{Binding Test}"/>
    </Grid>
</Window>

Если вы используете интерфейсы для своих ViewModels, довольно быстро создать экземпляр Design, просто используя Visual Studio для реализации всего свойства Interface и присвойте ему некоторые значения по умолчанию (для свойства, чтобы у вас есть данные примера в вашем ViewModel для проверки привязок работайте правильно).

Это требует от вас создания отдельных ViewModels времени разработки и ваших реальных ViewModels, что не так плохо, как кажется. Это дает вашему дизайнеру интерфейса возможность работать с ним, даже если реальный ViewModel еще не закончен/реализован.