2016-03-21 4 views
4

Как я могу отменить выход из определенной формы после нажатия кнопки Отмена (или X в верхнем правом углу или Esc)?Как отменить закрытие окна в приложении MVVM WPF

WPF:

<Window 
    ... 
    x:Class="MyApp.MyView" 
    ... 
/> 
    <Button Content="Cancel" Command="{Binding CancelCommand}" IsCancel="True"/> 
</Window> 

ViewModel:

public class MyViewModel : Screen { 
    private CancelCommand cancelCommand; 
    public CancelCommand CancelCommand { 
    get { return cancelCommand; } 
    } 
    public MyViewModel() { 
    cancelCommand = new CancelCommand(this); 
    } 
} 

public class CancelCommand : ICommand { 

    public CancelCommand(MyViewModel viewModel) { 
    this.viewModel = viewModel; 
    } 

    public override void Execute(object parameter) { 
    if (true) { // here is a real condition 
     MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show(
     "Really close?", "Warning", 
     System.Windows.MessageBoxButton.YesNo); 
     if (messageBoxResult == MessageBoxResult.No) { return; } 
    } 
    viewModel.TryClose(false); 
    } 

    public override bool CanExecute(object parameter) { 
    return true; 
    } 
} 

Текущий код не работает. Я хочу, чтобы пользователь оставался в текущей форме, если он выбирает «Нет» во всплывающем диалоговом окне. Кроме того, переопределение CanExecute не помогает. Он просто отключает кнопку. Я хочу разрешить пользователю нажать кнопку, но затем уведомить его/ее, что данные будут потеряны. Может быть, мне нужно назначить прослушиватель событий на кнопку?

EDIT:

мне удалось показывать всплывающие окна на кнопку Отмена. Но я все еще не могу управлять кнопкой Esc или X (вверху справа). Кажется, меня смутила кнопка Отмена, потому что метод Execute выполняется, когда я нажимаю кнопку X или Esc.

EDIT2:

Я изменил вопрос. Это было «как отменить кнопку« Отмена ». Однако это было не то, что я искал. Мне нужно отменить кнопку Esc или X. В 'MyViewModel' добавляет:

 protected override void OnViewAttached(object view, object context) { 
      base.OnViewAttached(view, context); 
      (view as MyView).Closing += MyViewModel_Closing; 
     } 

     void MyViewModel_Closing(object sender, System.ComponentModel.CancelEventArgs e) { 
      if (true) { 
       MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show(
        "Really close?", "Warning", 
        System.Windows.MessageBoxButton.YesNo); 
       if (messageBoxResult == MessageBoxResult.No) { 
        e.Cancel = true; 
       } 
      } 
     } 

Это решило мою проблему. Тем не менее, мне нужна ICommand, чтобы понять, на какую кнопку нажали, Сохранить или Отменить. Есть ли способ устранить использование события?

+3

ли ваш 'viewModel.TryClose (ложь)' функция отправляет событие в вашей точки зрения, чтобы закрыть диалоговое окно? Если это так, вы можете удалить 'IsCancel =" true "из кода xaml. Эта часть заставляет форму закрываться. –

+0

@ qqww2, если я удалю IsCancel = "true", тогда, если я нажму Esc, он не закроет окно. Я хочу, чтобы окно было закрыто на Esc. –

+1

Зарегистрируйте 'KeyBinding' в вашей команде. [Здесь] (http://stackoverflow.com/questions/19697106/create-key-binding-in-wpf) является примером. –

ответ

4

Вы пытаетесь выполнить работу View в классе ViewModel. Пусть ваш класс View обработает запрос на закрытие и должен ли он быть отменен или нет.

Чтобы отменить закрытие окна, вы можете подписаться на событие просмотра Closing и установить CancelEventArgs.Cancel в true после показа MessageBox.

Вот пример: за

<Window 
    ... 
    x:Class="MyApp.MyView" 
    Closing="OnClosing" 
    ... 
/> 
</Window> 

Код:

private void OnClosing(object sender, CancelEventArgs e) 
{ 
    MessageBoxResult result = MessageBox.Show("Really close?", "Warning", MessageBoxButton.YesNo); 
    if (result != MessageBoxResult.Yes) 
    { 
     e.Cancel = true; 
    } 

    bool shouldClose = ((MyViewModel) DataContext).TryClose(false); 
    if(!shouldClose) 
    { 
     e.Cancel = true; 
    } 
} 
+0

Проблема заключается в том, что View не знает, должно ли оно быть закрыто или нет. Я не вижу, как я могу получить доступ к данным ViewModel. –

+0

Хорошо. Можете ли вы подробно объяснить, какой алгоритм закрывает окно? –

+0

Я назначаю обработчик в ViewModel даже в OnClosing. Как я сказал после EDIT2. Однако в этом случае я не могу различить, КАК был закрыт. Я имею в виду, без добавления дополнительных флагов, которые я установлю в ICommand. –

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