WPF + Caliburn Micro:如何捕捉窗口关闭事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24699973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:08:15  来源:igfitidea点击:

WPF + Caliburn Micro: how to catch Window Close event?

c#wpfcaliburn.micro

提问by MagB

I am new in Caliburn Micro and learn it from this helloworld example. In the example there are only 2 views (.xaml) of type Application and UserControl, and 1 view model.

我是 Caliburn Micro 的新手,是从这个 helloworld 示例中学习的。在示例中,只有 2 个 Application 和 UserControl 类型的视图 (.xaml) 和 1 个视图模型。

I avoid to use code behind. Therefore I have only view and view model. I want to know how to catch the window close event of my helloworld applicationso I can handle it in view model. My target: when user is going to close the app by pressing close [x] button on top-right corner the app gives feedback to the user.
I have read about IViewAware and IScreen, but I find no specific example related to my question.

我避免使用后面的代码。因此我只有视图和视图模型。我想知道如何捕获 helloworld 应用程序的窗口关闭事件,以便我可以在视图模型中处理它。我的目标:当用户要通过按右上角的关闭 [x] 按钮关闭应用程序时,应用程序会向用户提供反馈。
我已经阅读了有关 IViewAware 和 IScreen 的内容,但没有发现与我的问题相关的具体示例。

A simple sample code for view and view model are highly appreciated. Thanks in advance.

高度赞赏视图和视图模型的简单示例代码。提前致谢。

PS. I use VS2013, C#.

附注。我使用 VS2013,C#。

回答by 123 456 789 0

What you can do is in your Viewyou can attach Caliburn Microby using

你可以做的是在View你可以Caliburn Micro通过使用附加

cal:Message.Attach="[Event Closing] = [Action OnClose($eventArgs)]"

So it will look like

所以它看起来像

<Window cal:Message.Attach="[Event Closing] = [Action OnClose($eventArgs)]">

And on your ViewModelyou can just define a public method that says OnClosewith CancelEventArgsas the parameter and you can handle it from there.

和你的ViewModel,你可以只定义,说一个公共方法OnCloseCancelEventArgs作为参数,你可以从那里处理它。

回答by gcores

If your ViewModel inherits Screen, Caliburn Micro has some methods that you can override like

如果您的 ViewModel 继承了 Screen,则 Caliburn Micro 有一些您可以覆盖的方法,例如

protected override void OnDeactivate(bool close); 

this is called when a screen is closed or deactivated or

当屏幕关闭或停用或

public override void CanClose(Action<bool> callback)

you can check CanClose usage here

您可以在此处查看 CanClose 的使用情况

回答by gcores

If you are using the BootstrapperBase class you can use:

如果您使用的是 BootstrapperBase 类,您可以使用:

protected override void OnExit(object sender, EventArgs e)

回答by BTownTKD

You're looking for a way to bind an Event to a Command. The typical approach here is to use the EventToCommandbehavior from MVVMLight.

您正在寻找一种将事件绑定到命令的方法。这里的典型方法是使用MVVMLight 的 EventToCommand行为。

Example usage (from the linked article):

示例用法(来自链接的文章):

<StackPanel Background="Transparent">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="Tap">
      <command:EventToCommand
        Command="{Binding Main.NavigateToArticleCommand,
          Mode=OneWay,
          Source={StaticResource Locator}}"
        CommandParameter="{Binding Mode=OneWay}" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
  <!--...-->
</StackPanel>

For your specific scenario, you are not using MVVMLight. Since that framework is open-source, you could copy the implementation of EventToCommand into your own project, or - more simply - you can use the InvokeCommandAction, which is part of the System.Windows.Interactivity.dll library, included with Expression Blend.

对于您的特定场景,您没有使用 MVVMLight。由于该框架是开源的,您可以将 EventToCommand 的实现复制到您自己的项目中,或者 - 更简单地 - 您可以使用InvokeCommandAction,它是 System.Windows.Interactivity.dll 库的一部分,包含在 Expression Blend 中。

Example of InvokeCommandAction:

InvokeCommandAction 示例:

<TextBox x:Name="TicketNumber">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="KeyDown">
            <i:InvokeCommandAction Command="{Binding OpenTicketCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

Lastly, this entire MVVM dogma that you "can't have any code behind" has been shot down time| and| timeagain (that last link is particularly relevant). MVVM is supposed to be unit-testable, and separates the "View logic" from the "Business logic." The "Close" event is admittedly a bit of a gray area between View and Business logic. But, if you can write an event handler in your code behind, which invokes your ViewModel's appropriate method or command, and if you can unit test that code, then you're as good as gold. Don't worry about removing all traces of code-behind from your project.

最后,这整个MVVM教条,你“不能有任何的代码背后”已经被击落的时间| | 时间再一次(即最后一个环节是特别重要)。MVVM 应该是可单元测试的,并将“视图逻辑”与“业务逻辑”分开。“关闭”事件无疑是视图和业务逻辑之间的灰色区域。但是,如果您可以在后面的代码中编写一个事件处理程序,它会调用您的 ViewModel 的适当方法或命令,并且如果您可以对该代码进行单元测试,那么您就像黄金一样出色。不要担心从项目中删除所有代码隐藏痕迹。