在使用MVVMLight Toolkit的WPF应用程序中,如果需要取消窗口关闭事件,我想知道您的意见,最好的实现方式是什么。
在Window.Closing事件中,我可以设置e.Cancel = true,这可以防止关闭窗体。要确定是否允许关闭或应该阻止关闭是在ViewModel上下文中的。
一个解决方案可能是定义一个Application变量,并在视图代码后台的普通事件处理程序中查询它?
谢谢
MVVM Light 提供了 EventToCommand
:
这样你就可以在 XAML 中将关闭事件与 VM 绑定。
<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
,并且只需使用来自 VM 的简单的 bool
(将此 bool 绑定到 Behavior) 来指示关闭事件应该被取消。
更新:
要使用 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>
在此示例中,我有一个 Button
用于切换来自 VM 的布尔属性 CancelClose
,该属性指示是否应取消 Closing
事件。这将让您测试 Behavior
InvokeCommandAction
和在关闭事件上的行为,那么行为会首先被调用。 - XAMlMAXMessages
进行控制,例如: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
的地方,你都可以控制应用程序何时关闭,并且可以取消它。
希望这能帮到你...