Правильно ли для ViewModel внедрить себя в свои дочерние ViewModels? - PullRequest
0 голосов
/ 23 июня 2009

Я создал Тестовое приложение MVVM , которое во время выполнения читает файл XML для динамического создания меню и, исходя из того, что выбрал пользователь, загружает в UserControl этой страницы динамически . В результате получается хороший шаблон MVVM, который позволяет вам иметь одну пару View / ViewModel на страницу , определенную в файле XML. Очень мило.

Так что теперь я просто добавил для разработчика возможность создать кнопку на одной странице, которая переходит на другую страницу . Я делаю это в MainViewModel. Я создаю коллекцию ViewModel в ObservableCollection, и когда я создаю каждый из них, я внедряю саму MainViewModel (this) в каждый конструктор UserControl-ViewModel, Таким образом, каждый UserControl имеет внутри себя MainViewModel, чтобы разработчик мог манипулировать приложением (например, вызывать SwitchPage (idCode)) через MainViewModel.

Также любое глобальное состояние , которое мне нужно сохранить, я могу сохранить в MainViewModel, к которой имеет доступ каждый UserControl.

Кроме того, каждый UserControl (PageItem) имеет полный доступ ко всем остальным UserControls , что дает мне в основном контроль над всем в приложении из любого UserControl, чего я пытался добиться в MVVM приложение в течение длительного времени.

Так что мой вопрос: Является ли этот вид внедрения ViewModel полезным / известным шаблоном или есть проблемы с внедрением ViewModel в его дочерние ViewModels? Мне кажется, что это рекурсивно, но, кажется, работает нормально мне функциональность, которую я хочу до сих пор. Из того, что я узнал из архитектуры библиотеки составных приложений, похоже, что здесь происходит нечто подобное, например: в приведенном ниже коде я могу добавить другие объекты приложения в мои модели ViewModel по мере необходимости.

public MainViewModel()
{

    PageItems pageItems = PageItems.Create("all");

    foreach (PageItem pageItem in pageItems.Collection)
    {
        string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
        string viewModelName = assemblyName + ".ViewModels.PageItem" + StringHelpers.ForcePascalNotation(pageItem.IdCode) + "ViewModel";
        var type = Type.GetType(viewModelName);
        var viewModel = Activator.CreateInstance(type, this, pageItem) as ViewModelPageItemBase;
        AllPageItemViewModels.Add(viewModel);
    }

    CurrentPageItemViewModelIndex = 0;
    LoadCurrentPageItemViewModel();
}

1 Ответ

6 голосов
/ 23 июня 2009

Я не вижу это как неправильное или правильное, но больше о том, насколько связан ваш дизайн. Я обычно начинаю с подхода, который вы упомянули (дочерняя виртуальная машина ссылается на родительскую виртуальную машину), а затем отделяется, если я считаю, что он слишком громоздкий. Ваш первый выбор не обязательно должен быть последним - вы можете реорганизовать свой код по мере его развития.

Возможные альтернативы:

  • дочерняя ВМ вызывает событие, которое родитель слушает (шаблон наблюдателя). Родительская ВМ знает детей близко, но ребенок не знает родителей.
  • дочерняя виртуальная машина публикует событие в концентраторе событий, который слушает родитель (шаблон-посредник). Ни ребенок, ни родитель не знают друг друга. Они знают только о посреднике.
...