Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

Принцип, структура и использование WPF фреймворка mvvmlight

#c_sharp #wpf #mvvm #mvvm_light


Пытаюсь разобраться с MVVM Light. И чем дальше, тем страшнее. Вопросы возникают как
снежный ком. В сети не нашел ни одной статьи, где бы простым русским языком объяснялся
бы mvvm-light и его практическое применение. Ниже я приведу места и моменты, которые
вызывают у меня непонимание.

Установил на VisualStudio 2015 MVVM Light, создал новый проект MvvmLight(WPF451).
В проекте создались следующие файлы и папки:

[Design]
    DesignDataService.cs
[Model]
    DataItem.cs
    DataService.cs
    IDataService.cs
[Skins]
    MainSkin.xaml
[ViewModel]
    MainViewModel.cs
    ViewModelLocator.cs
App.xaml
App.xaml.cs
MainWindow.xaml
MainWindow.xaml.cs


В файле App.xaml видим следующее .
Как было выяснено здесь, это не подходит по ряду причин, а поэтому нужно удалить этот
атрибут и в перегруженном методе OnStartup класса App создать экземпляр необходимой
модели представления и установить её как DataContext, примерно так:

public partial class App : Application {

    MainViewModel mainVM = new MainViewModel();

    static App() {
        DispatcherHelper.Initialize();
    }

    protected override void OnStartup(StartupEventArgs e) {
        base.OnStartup(e);
        new MainWindow() { DataContext = mainVM }.Show();
    }
}


, но при использовании в созданном проекте mvvm-light класс MainViewModel принимает
в конструкторе IDataService dataService. В проекте так и не нашел каким образом создается
этот dataService. Для каждой ли модели представления нужно этот dataService создавать?
Как, когда и где он используется?

Также в созданном проекте присутствует класс ViewModelLocator. В комментарии класса
указан пример использования:

/*
In App.xaml:

    


In the View:
DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
*/


, но вроде же как явное указание DataContext в XAML неправильно?! Или я не прав?!
Для чего и как он используется?  

В code-behind представления MainWindow к событию Closing добавляется очистка ViewModelLocator:


Closing += (s, e) => ViewModelLocator.Cleanup();


, но в ViewModelLocator ничего не добавляется. Или это происходит где-то далеко за
кулисами?!

В файле MainWindow.xaml существует привязка к ресурсу:


    
        
            
        
    



Как я понял, это используется только для работы с визуальным редактором и в рабочей
версии никакой роли не играет. Поправьте меня, если я не прав.



В сети присутствует множество примеров mvvm-light, но они все сводятся к слепому
следованию инструкциям, без пояснения для чего это делается и как это в последствии
используется. Предвидя упреки об изучении мат.части, отмечу, что мне лично материал
легче усваивается на практике. И не хотелось бы колотить себе шишки, а перенять опыт
знающих людей и сразу учить как нужно делать, а не как можно. Может существует какой-либо
проект в сети, который подробно описывает использование mvvm-light фреймворка на русском?
    


Ответы

Ответ 1



Самое простое - следовать рекомендации, и делать все через ViewModelLocator. DataService создается через инъекции из IoС контейнера. Так регистрация происходит в ViewModelLocator.cs в конструкторе пишем SimpleIoc.Default.Register(); где DebugDataContext - конкретная реализация интерфейса IDataTask например база данных для дебага, а в продакшене будет с другого места браться (но это уже совсем другая история). Регистрируем VM SimpleIoc.Default.Register(); Выставляем ее на публику public MainViewModel Main => ServiceLocator.Current.GetInstance(); Все это есть уже по умолчанию, для других форм просто по аналогии. И вот когда вьюха будет обращаться к VM посредством того кода в XAML автоматически через IoC будет цепляться нужный источник данных. Вам там ответили, что вьюха не должна создавать VM. но она и не создает, создает IoC-контейнер, вьюха только запрашивает его экземпляр. Так что вам там не совсем верно ответили, без инъекций все действительно так, но в MVVM Light уже есть IoC и вся парадигма строится вокруг инъекций В коде можно тоже, если очень хочется, но лично я не вижу в этом смысла mainVM = ServiceLocator.Current.GetInstance(); Конечно всё это ИМХО, у VlaD'a свои взгляды, у меня свои, и MVVM это не святое писание, а просто идея и используют ее по разному, но по задумке создателей MVVM Light это должно делаться примерно так как я описал.

Комментариев нет:

Отправить комментарий