Возможно, я пропустил этот момент, я уже давно копался, посмотрел на the different approaches, чтобы привязать взгляды и просмотреть модели и как перемещаться между ними.WPF от ICommand обратно в MainView
Установка:
- 1 MainWindow (ViewModel:
MainWindowViewModel
) - MainWindow содержит некоторые визуальные эффекты и
ContentControl
, который переплетены кViewModelBase
. Поэтому вMainWindowViewModel
я могу установить любой другой вид (модель) для отображения. - Получил два пользовательских элемента управления, один из которых - это форма входа в систему, а другая - индикатор загрузки.
Внутри App.xaml
<DataTemplate DataType="{x:Type vms:LoginViewModel}">
<Views:LoginView />
</DataTemplate>
<DataTemplate DataType="{x:Type vms:LoadingViewModel}">
<Views:LoadingView />
</DataTemplate>
Цель: Из ICommand внутри LoginViewModel
вернуться к MainWindowViewModel
, долго с данными формы. MainWindowViewModel
затем переключится на LoadingViewModel
, выполните асинхронный вызов службы. В следующий раз при запуске при обновлении токена обновления я покажу LoadingViewModel
вместо формы входа. По завершении откроется новое окно (или что-то еще, пока не знаю).
Проблема: Большинство примеров показывают, как это сделать, когда кнопка находится вне обоих пользовательских элементов управления, поэтому, когда ICommand находится внутри MainWindow, то это было бы легко, но это событие вызывается из одного из подвидов , Использование PropertyChange кажется немного выключенным.
Давайте копаем код, мы?
MainWindow.xaml, только одна важная строка
<ContentControl Content="{Binding CurrentView}" Grid.Column="1" Grid.Row="1" />
MainWindow.xaml.cs, в конструктор
this.DataContext = new MainWindowViewModel();
MainWindowViewModel
public class MainWindowViewModel
{
public ViewModelBase CurrentView { get; set; }
public MainWindowViewModel()
{
CurrentView = new LoginViewModel();
}
}
LoginViewModel
public class LoginViewModel : ViewModelBase
{
public DelegateCommand loginCommand { get; set; }
public LoginViewModel()
{
loginCommand = new DelegateCommand(Execute, CanExecute);
}
private bool CanExecute()
{
return true;
}
private void Execute()
{
//I need to go to MainWindowViewModel
throw new NotImplementedException();
}
//more properties below heere.
ViewModelBase
наследует от BindableBase
(от Prism), так что обрабатывает события PropertyChanged. В свойствах моих моделей просмотра используются правильные методы SetProperty
. Я предпочитаю не использовать область Призма, IEventAggregator или Unitiy.
Solutions
Что приходит на ум посылает интерфейс длинный с конструктором, и использовать интерфейс, чтобы сделать «обратные вызовы» к MainWindowViewModel
, но я предполагаю, что это даст ошибки, так как я буду измените представление и, таким образом, установите MainWindowViewModel.CurrentView
на что-то другое, оставив LoginViewModel
null. Поскольку запрос исходит от этого объекта, я могу себе представить, что это не очень хорошо.
Как об обработке все это в поглотителе и сеттер вашего'ViewModelBase'. Это единственное место, где одновременно вы будете иметь как старые, так и новые ценности в вашем диапосале. – XAMlMAX
Вы делаете это неправильно. ViewModel не должен ничего знать о представлениях. Вся идея заключается в том, что ваши Views и ViewModels должны быть полностью разделены, и вы должны полностью изменить свой View или ViewModel, и он все равно должен работать. –
@NawedNabiZada Да, я знаю. Вот почему я держу 3 модели взгляда раздельными. Я не вижу, что я что-то делаю от MVVM здесь, до сих пор это просто базовая реализация. И иногда есть требования, которые делают его немного меньше MVVM, возможно, это один из них, но я ищу решение, которое наилучшим образом соответствует MVVM и, конечно же, сплошному коду. XAMIMAX: Uhhm, это 2 разных экземпляра, и мне не нужны старые и новые значения. – CularBytes