Доброго времени суток, Господа. Прошу помочь мне в моем спаггети-коде и разложить все по полочкам. Суть следующая:
Есть окно, в этом окне есть два контрола - Menu и Frame. Также имеется страница Page, которая указана в Frame.
Меню представляет из себя выбор категорий, а страница, которая отображается в Frame, представляет из себя изделия:
Итак. У окна есть свой VM - WindowViewModel. В этом VM есть вложенное VM - MenuViewModel, которое является View Model'ом моего меню. У этого MenuViewModel есть открытое свойство:
Category selectedMenuItem;
public Category SelectedMenuItem
{
get => selectedMenuItem;
set { Set( ref selectedMenuItem, value ); }
}
которое представлет из себя выбранный пункт меню, и отражается на определенную категорию Category.
До этого момент должно быть все понятно. Теперь страница:
Каждая страница наследуется вот от такого класса( не буду весь класс пилить сюда, оставлю только самое основное):
public class BasePage<VM> : Page where VM : BaseViewModel, new()
{
VM viewModel;
public VM ViewModel
{
get { return viewModel; }
set
{
if( viewModel == value )
return;
viewModel = value;
this.DataContext = viewModel;
}
}
public BasePage()
{
ViewModel = new VM();
}
}
Итого мы имеем вот такую страницу, для отображения изделий:
public partial class ProductListPage : BasePage<ProductListViewModel>
{
public ProductListPage() : base()
{
InitializeComponent();
}
}
ProductListViewModel - это VM для страницы отображения изделий. Это большой класс, в котором написаны тонкости вывода изделий, поэтому не очень хочется приводить его здесь. Единственное что скажу, это то, что в конструкторе этого VM идет запрос у репозитория на получение всех изделий из БД, чтобы при первом старте страницы, отображались все товары, всех категорий.
А теперь собственно вопрос. Как правильно сделать взаимодействие между двумя VM'ами - MenuViewModel и ProductListViewModel. После изменения текущего пункта меню, в MenuViewModel срабатывает команда, в обработчике этой команды обновляется свойство SelectedMenuItem. Как теперь известить ProductListViewModel о том, что нужно отфильтровать список изделий?
Меня не интересуют кривые решения этой проблемы. Я и сам могу это реализовать. Мне бы хотелось услышать изящные решения, которые я, возможно, буду применять в будущем. Спасибо
Окей, попробую ответить на этот вопрос в меру своего понимания.
Для взаимодействия VM-объектов между собой они должны быть связаны. Таким образом, между объектами должна существовать зависимость.
Для того, чтобы установить зависимость между объектами, есть много путей. Либо один из группы объектов (обычно «родительский») берёт на себя ответственность по созданию и настройке объектов-потомков, либо (если настройки и связи становятся слишком сложны, чтобы быть ответственностью одного VM-объекта) эта ответственность делегируется «внешнему», управляющему объекту, чьё единственное задание — связать VM-объекты между собой правильным образом.
Для того, чтобы один подобъект «узнал» о другом, я бы использовал традиционные средства «ручного» внедрения зависимостей: конструктор с нужными параметрами, на крайний случай — открытые для записи свойства. Полновесное внедрение зависимостей в моей практике использовать для простой цели связи VM-объектов не приходилось, и было практически всегда излишним.
Для вашего случая я бы связал MenuViewModel (или, возможно, лишь SelectedMenuItem) с ProductListPage, чтобы она могла сама следить за изменением SelectedMenuItem'а и надлежащим образом реагировать.
Важное замечание. Для того, чтобы возможно было связывание VM (да и просто в соответствии с паттерном MVVM, если вы его придержтваетесь), у вас VM-объекты наподобие ProductListViewModel не должны конструироваться во View, и должны иметь конструктор с параметрами. DataContext для окна должен устанавливаться самой программой, а DataContext для внутренних контролов должен в большинстве случаев устанавливаться через привязку к свойствам DataContext'а охватывающих контролов.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости