WPF (MVVM): Закрытие представления от Viewmodel?

Я предпочитаю этот способ поместить универсальные типы в набор:

interface IList
{
  void Add (object item);
}

class MyList<T> : List<T>, IList
{
  public void Add (object item)
  {
    base.Add ((T) item); // could put a type check here
  }
}

class Program
{
  static void Main (string [] args)
  {
    SortedDictionary<int, IList>
      dict = new SortedDictionary<int, IList> ();

    dict [0] = new MyList<int> ();
    dict [1] = new MyList<float> ();

    dict [0].Add (42);
    dict [1].Add ("Hello"); // Fails! Type cast exception.
  }
}

, Но Вы действительно потеряли чеки типа во время компиляции.

46
задан mark smith 27 September 2009 в 19:17
поделиться

7 ответов

Изменить: См. мое сообщение в блоге для более подробного объяснения.

Когда мне нужно этого добиться, я использую созданный мной интерфейс IRequestCloseViewModel.

Этот интерфейс содержит только одно событие: RequestClose. Это событие вызывается ViewModel (который наследуется от класса ViewModelBase и реализует IRequestCloseViewModel), когда он хочет закрыть связанный с ним вид.

В моем приложении все Window наследуются от абстрактного класса ApplicationWindow. Этот абстрактный класс уведомляется каждый раз, когда DataContext изменяется, и в обработчике проверяет, поддерживает ли DataContext IRequestCloseViewModel. В этом случае обработчик событий настроен на закрытие окна при возникновении события.

В качестве альтернативы, как сказал Кент, вы можете использовать контроллер экрана, который обрабатывает этот механизм во внешнем классе.

35
ответ дан 26 November 2019 в 20:23
поделиться

I would use an ApplicationController which instantiates the LoginViewModel and shows the LoginView. When the user proceeds with the login screen the ApplicationController closes the LoginView and shows the MainView with its MainViewModel.

How this can be done is shown in the sample applications of the WPF Application Framework (WAF) project.

2
ответ дан 26 November 2019 в 20:23
поделиться

Обычно для активации / деактивации экрана используется какой-то контроллер / ведущий / служба. MVVM не предназначен быть единым шаблоном, чтобы управлять ими всеми . Вам нужно будет объединить его с другими шаблонами в любом нетривиальном приложении.

Тем не менее, в некоторых ситуациях имеет смысл иметь модель представления, которая управляет жизненным циклом дочерних моделей представления. Например, у вас может быть EditorViewModel , которая управляет коллекцией дочерних моделей представлений - по одной для каждого редактируемого документа. В этом случае простое добавление / удаление в / из этой коллекции может привести к активации / деактивации представления. Но это не похоже на ваш вариант использования.

8
ответ дан 26 November 2019 в 20:23
поделиться

Вы можете создать команду, которая прикрепляется к окну и при выполнении закрывает окно. Затем вы можете привязать эту команду к свойству в вашей модели представления и выполнить команду, когда вы хотите закрыть окно.

4
ответ дан 26 November 2019 в 20:23
поделиться

Не уверен, какой MVVM-фреймворк вы используете, но большинство из них содержат что-то вроде решения для обмена сообщениями / уведомлениями, что позволяет легко регистрировать вещи для сообщений, которые отправляются. Нет причин, которые я могу представить, чтобы ваше представление не могло зарегистрироваться для сообщения типа "CloseWindowsBoundTo" и viewModel в качестве отправителя. Тогда в вашем представлении вы можете просто зарегистрироваться для этого сообщения и сравнить ваш текущий датаконтекст с отправителем. Если они совпадают, закройте окно.

Просто, и позволяет абстрагировать ваше представление от вашей модели представления.

Вот мой подход с использованием MVVM-light toolkit:

В ViewModel:

public void notifyWindowToClose()
{
    Messenger.Default.Send<NotificationMessage>(
        new NotificationMessage(this, "CloseWindowsBoundToMe")
    );
}

И в View:

Messenger.Default.Register<NotificationMessage>(this, (nm) =>
{
    if (nm.Notification == "CloseWindowsBoundToMe")
    {
        if (nm.Sender == this.DataContext)
            this.Close();
    }
});
22
ответ дан 26 November 2019 в 20:23
поделиться

Этот ответ показывает другой способ сделать это:

Как ViewModel должен закрывать форму?

Он использует присоединенное свойство для привязки свойства окна DialogResult к свойству ViewModel. При установке для DialogResult значения true или false представление закрывается.

2
ответ дан 26 November 2019 в 20:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: