2015-02-09 2 views
0

Мне нужно закрыть модальное окно из ViewModel на основе команды щелчка, которая запускается в элементе управления, который представлен в окне.WPF & MVVM - Закрыть окно изнутри Child control

Итак, у меня есть MainViewModel, JimViewModel, JimWindow и JimControl. MainViewModel создает JimWindow и устанавливает его DataContext в JimViewModel. JimWindow содержит JimControl, который содержит кнопку. Когда эта кнопка нажата, я хотел бы вызвать команду, которая каким-то образом закрывает JimWindow.

Я видел несколько вопросов, которые отвечают на это относительно закрытия окна из фактического окна (передавая экземпляр окна в команду на ViewModel), но он не переводит на то, что я хочу делать.

Я не использую рамки, поэтому у меня нет удобного посланника, чтобы помочь мне. Может ли кто-нибудь помочь? Это случай как-то ссылаться на Имя родительского окна из элемента управления?

+0

Поскольку закрытие окна строго просмотр связанных, я бы сказал, перекрывая событие для вызова команды (при необходимости) и закрыть окно лучше, чем модель представления, обеспечивающая эту функциональность в команде. – chris

+0

Где бы этот звонок был закрыт, правда? Кнопка, которая закрывает окно, находится в элементе управления, который находится внутри окна. Должно ли окно передать ссылку на элемент управления? – jimbo

+0

Функция будет переопределена в контексте окна уже. То есть переопределяющим классом будет окно, и поэтому можно просто вызвать 'Close()'. Это добавляет код в место, где код должен быть дефицитным, но я не думаю, что это код, который принадлежит VM. У меня недостаточно опыта, чтобы узнать все другие доступные варианты. – chris

ответ

1

MainViewModel не следует создавать окна, по крайней мере, не напрямую. Виртуальные машины должны создавать только виртуальные машины. Окно является частью мира взглядов.

Если вам нужен ваш JimVM, размещенный в окне, тогда было бы лучше, если бы какой-то WindowService был удален за интерфейс. MainVM затем просто создает JimVM и присваивает его оконному сервису для размещения в окне

После того, как вы вставили бит Windows в отдельную службу, вы можете сделать все, что вам нужно. У меня было бы JimVM выставить CloseCommand и событие Closed. Вы можете связать свою кнопку JimControl с номером CloseCommand, и служба Windows может подписаться на событие Close и разорвать окно при его запуске.

Это сохраняет вид и материал виртуальной машины полностью раздельными. Единственное, что знает, как склеить их вместе, - это оконный менеджер.

0

Хотя идея ViewModel, создающая View, звучит немного назад, вы можете использовать обмен сообщениями, например. TinyMessenger или Messenger, который поставляется с MVVMLight.

Затем вы можете зарегистрировать сообщение в своем представлении ViewModel и отправить его из любого места. Действительно простейший пример использования MVVMLight может быть:

// custom message 
public class CloseMessage : MessageBase 
{ 
    public CloseMessage(object sender) 
     :base(sender) 
    {} 
} 

// main view registers for a message 
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     Messenger.Default.Register<CloseMessage>(this, message => 
     { 
      // do teh stuff 
     }); 
    } 
    ... 
} 

// command bound to close button sends the message 
private void YourCloseMainViewCommand() 
{ 
    Messenger.Default.Send(new CloseMessage(this)); 
} 
+0

Я не уверен, что я следую. Я действительно мало знаю о классах Messenger.Будет ли JimWindow создан как экземпляр в классе MainWindow (или, скорее, MainControl в моем случае)? – jimbo

+0

Это даже не имеет значения. Вы можете регистрировать/отправлять сообщения там, где вам нужно. –

+1

На самом деле у меня есть старое репо, настроенное с демонстрацией сообщений MVVM на https://github.com/mikkoviitala/cross-viewmodel-communication, если вы хотите заглянуть. –

Смежные вопросы