Окно отмены WPF MVVM.Заключительное мероприятие


В приложении WPF вместе с инструментарием MVVMLight я хотел бы узнать ваше мнение, что лучше всего реализовать, если мне нужно отменить событие закрытия окна. в окне.Закрывающее событие я могу установить e. Cancel = true, что предотвращает закрытие формы. Определить, разрешено ли закрытие или должно быть предотвращено, можно в контексте ViewModel.

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

Спасибо

2 6

2 ответа:

С помощью MVVM Light вы получили EventToCommand:

Таким образом, вы можете в xaml подключить событие закрытия к виртуальной машине.

<Window ...
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:command="http://www.galasoft.ch/mvvmlight">
<i:Interaction.Triggers>
  <i:EventTrigger EventName="Closing">
    <command:EventToCommand Command="{Binding ClosingCommand}"
                            PassEventArgsToCommand="True" />
  </i:EventTrigger>
</i:Interaction.Triggers>

А в ВМ:

public RelayCommand<CancelEventArgs> ClosingCommand { get; private set; }

ctor() {
  ClosingCommand = new RelayCommand<CancelEventArgs>(args => args.Cancel = true);
}

Если вы не хотите передавать CancelEventArgs в VM :

Вы всегда можете использовать аналогичный подход с Behavior и просто использовать простой bool из виртуальной машины(привязать этот bool к поведению), чтобы указать, что событие закрытия должно быть отменено.

Обновление:

Ссылка на скачивание для следующего пример

Чтобы сделать это с помощью Behavior , Вы можете просто иметь Behavior, например:

internal class CancelCloseWindowBehavior : Behavior<Window> {
  public static readonly DependencyProperty CancelCloseProperty =
    DependencyProperty.Register("CancelClose", typeof(bool),
      typeof(CancelCloseWindowBehavior), new FrameworkPropertyMetadata(false));

  public bool CancelClose {
    get { return (bool) GetValue(CancelCloseProperty); }
    set { SetValue(CancelCloseProperty, value); }
  }

  protected override void OnAttached() {
    AssociatedObject.Closing += (sender, args) => args.Cancel = CancelClose;
  }
}

Теперь в xaml:

<i:Interaction.Behaviors>
  <local:CancelCloseWindowBehavior CancelClose="{Binding CancelClose}" />
</i:Interaction.Behaviors>

Где CancelClose - свойство bool из виртуальной машины, которое указывает, следует ли отменить событие Closing или нет. В прилагаемом примере у меня есть Button для переключения этого bool из виртуальной машины, что должно позволить вам проверить Behavior

Вы можете управлять этим с помощью Messages, например:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Messenger.Default.Register<CloseApplicationMessage>(this, m => Close());
        Loaded += MainWindowLoaded;
        Closing += MainWindowClosing;
    }

    private void MainWindowClosing(object sender, CancelEventArgs e)
    {
        //Ask for saving
        var closingMessage = new ClosingApplicationMessage();
        Messenger.Default.Send(closingMessage);
        if (closingMessage.Cancel)
            e.Cancel = true;
    }
...

Сообщение mvvm:

public class ClosingApplicationMessage
{
    public bool Cancel { get; set; }
}
Таким образом, в любом месте, где вы слушаете ClosingApplicationMessage, Вы можете контролировать, когда приложение собирается закрыть, и можете отменить его. Надеюсь, это поможет...