2016-02-28 7 views
0

Возможно, я пропустил этот момент, я уже давно копался, посмотрел на 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. Поскольку запрос исходит от этого объекта, я могу себе представить, что это не очень хорошо.

+0

Как об обработке все это в поглотителе и сеттер вашего'ViewModelBase'. Это единственное место, где одновременно вы будете иметь как старые, так и новые ценности в вашем диапосале. – XAMlMAX

+0

Вы делаете это неправильно. ViewModel не должен ничего знать о представлениях. Вся идея заключается в том, что ваши Views и ViewModels должны быть полностью разделены, и вы должны полностью изменить свой View или ViewModel, и он все равно должен работать. –

+0

@NawedNabiZada Да, я знаю. Вот почему я держу 3 модели взгляда раздельными. Я не вижу, что я что-то делаю от MVVM здесь, до сих пор это просто базовая реализация. И иногда есть требования, которые делают его немного меньше MVVM, возможно, это один из них, но я ищу решение, которое наилучшим образом соответствует MVVM и, конечно же, сплошному коду. XAMIMAX: Uhhm, это 2 разных экземпляра, и мне не нужны старые и новые значения. – CularBytes

ответ

1

Хорошим способом общения является концепция Messenger (MVVM Light) или EventAggregator (Prism).

В основном это паб/подсистема памяти.

Вот пример из статьи на MSDN

MVVM - Messenger and View Services in MVVM

Using the event aggregator pattern to communicate between view models

Я не уверен, рамки/библиотеки вы используете, но рамки наиболее MVVM имеют схожую концепцию lousily в сочетании связи ,

Это очень эффективная концепция обработки сообщений. Но с большой силой приходит ответственность =) ...

HTH

+0

Спасибо, я знаю концепцию, я упомянул в своем вопросе, что я не использую ее. Я не смотрел на MVVM Light, но мне не нравится, как Prism хочет, чтобы вы заполнили свой конструктор eventAggregator. Возможно, я буду использовать его для других сценариев позже. – CularBytes