Перефокусировка на трудных, непредвиденных требованиях является постоянной отравой программиста. Разработка через тестирование вынуждает Вас сфокусироваться на уже известных, приземленных требованиях и ограничивает Вашу разработку тем, что было уже предположено.
Думают об этом, Вы, вероятно, закончите тем, что разработали к определенным тестовым сценариям, таким образом, Вы не станете творческими и начнете думать, что "было бы здорово, если пользователь мог бы сделать X, Y, и Z". Поэтому, когда тот пользователь начинает быть всем взволнованным потенциальными прохладными требованиями X, Y и Z, Ваш дизайн может быть слишком твердо сфокусирован на уже указанных тестовых сценариях, и будет трудно корректироваться.
Это, конечно, является обоюдоострым мечом. При пребывании в течение всего времени, разрабатывая для каждого мыслимого, вообразимого X, Y, и Z, который мог когда-либо хотеть пользователь, Вы ничего никогда не будете неизбежно завершать. При завершении чего-то для любого (включая себя) будет невозможно иметь любую идею, что Вы делаете в своем коде/дизайне.
1) Вы можете унаследовать View1Model и View2Model от одной базовой ViewModel и определить там ShowMainMenu.
или (это мой подход)
Создайте RootView с ContentPresenter, который покажет все ваши представления . Создайте RootVeiwModel со свойством ViewContent. Привязать свойство Content ContetnPresenter к свойству ViewContent RootViewModel. Вы можете использовать объект
как тип ViewContent, но я советую вам определить интерфейс, который поддерживается MainVView1Model, View1Model и View2Model. Изменение ViewContent должно вызывать ProprtyChangedEvent.
Определите ShowMainViewCommand в RootViewModel, который просто изменит ViewContent на MainViewModel (и он будет отображаться как MainView). Затем привяжите свойство Command кнопки в View1 и View2 к этой команде, например, таким образом:
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RootView}},
Path=DataContext.ShowMainViwe}
Вот код, объясняющий, что я пытаюсь сказать:
RootView.xaml
...
<ContentPresenter Content={Binding ViewContent} />
...
RootViewModel.ca
class RootViewModel : INotifyPropertyCahnged
{
...
private object _ViewContent;
public object ViewContent
{
get {return _ViewContent;}
set
{
_ViewContent = value;
if (PropertyChanged != null)
{
PropertyChanged ("ViewContent");
}
}
}
private RelayCommand _ShowMainView;
public ICommand ShowMainView
{
get
{
if (_ShowMainView == null)
{
_ShowMainView = new RelayCommand(x => ViewContent = new MainViewModel());
}
return _ShowMainView;
}
}
...
}
] 2) Добавить ссылку на MainViewModel на UC1ViewModel и UC2ViewModel - это способ повлиять на другие элементы управления. MainViwModel должен содержать свойства, которые содержат UC1ViewModel и UC2ViewModel. Элементы второго пользовательского элемента управления должны содержаться в ObservableCollection.
Я просто покажу вам, как это работает с помощью кода:
class UC1ViewModel : INotifyPropertyChanged
{
...
private MainViewModel _Parent;
public UC1ViewModel(MainViewModel parent)
{
_Panert = parent;
}
private RelayCommand _AddItemToUC2;
public ICommand AddItemToUC2
{
get
{
if (_AddItemToUC2 = null)
{
// UC2Content is UC2ViewModel
// Items is ObservableCollection
_AddItemToUC2 = new RelayCommand(x => _Parent.UC2Content.Items.Add(...));
}
return AddItemToUC2;
}
}
...
}
MainModel может иметь свойство для каждой UCxViewModel или, проще говоря, список ViewModel. Команда «Показать» создаст соответствующий UVxViewModel, подпишется на событие «OnClose», опубликованное UVxViewModel, и добавит его в список. MainView имеет элемент управления (например, Tab Control), связанный с этим списком, и DataTemplates, определяющие представления, которые будут использоваться для каждой модели UCxViewModel. Когда UVxViewModel запускает свое событие OnClose, MainModel удаляет его из списка, в результате чего соответствующее представление «закрывается».
Для части «Добавить элемент» модели представления должны совместно использовать один и тот же список элементов (модель). Затем UC2ViewModel может добавить элемент, и UC1View будет обновлен (при условии, что список реализует INotifyCollectionChanged).
Я нашел это объяснение очень полезным для понимания MVVM.