【问题标题】:Should I use the Closing event or override OnClosing?我应该使用 Closing 事件还是覆盖 OnClosing?
【发布时间】:2014-01-06 16:05:33
【问题描述】:

我有一个 WPF 项目,其中有一个带有自定义关闭逻辑的窗口。我希望在用户关闭窗口时运行一些代码。我知道有两种方法可以做到这一点,我想知道哪种方法更好:

选项 1) 处理 base.Closing 事件。

选项 2) 覆盖 OnClosing 方法。

这里有一些示例代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        base.Closing += this.MainWindow_Closing;
    }

    //Option 1
    void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        //close logic here, or
    }

    //Option 2
    protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
        //close logic here

        base.OnClosing(e);
    }
}

我能发现这两个选项之间的唯一区别是外观。我更喜欢选项 2,因为它对我来说看起来更干净。我更喜欢覆盖方法而不是处理事件。

这两个选项之间还有其他区别吗?我知道选项 1 是为其他一些类提供的,以处理此窗口的关闭事件。

编辑:我忘了提到我使用的是 .Net 4.0。看起来 .Net 4.5 有一个 OnFormClosing 事件,它弃用了 OnClosing 事件。我没有使用 OnFormClosing 事件。

【问题讨论】:

    标签: c# .net wpf


    【解决方案1】:

    监听其自己的事件的类有点傻。然而,这是设计人员的工作方式,它们被编写为生成事件处理程序分配,而不是自动生成方法覆盖。由于您没有使用设计器并自己编写事件处理程序分配,因此您绝对应该支持覆盖。少一件事你会做错,你不能忘记写作业。

    只有在您(或其他程序员)从 MainWindow 类中派生一个类时才真正重要。现在您可以选择如何编写 OnClosing() 方法:

    • 在 base.OnClosing() 调用之前添加您的自定义代码。您允许派生类更改您所做的决定。换句话说,对于这个事件,程序员可以强制 e.Cancel 回到 false。这是正常的方式。

    • 首先调用 base.OnClosing(),然后添加您的自定义代码。这使您可以牢牢控制,而派生类无法覆盖您的决定。当您的决定最重要和/或派生类可能无法正确覆盖您的选择时,您会这样做,这可能是因为只有您可以访问私有信息。

    • 不调用 base.OnClosing()。这可以防止派生代码看到该事件。当你彻底改变事件处理时,你会这样做。对于此事件,例如当您取消关闭并隐藏窗口时。

    【讨论】:

    • 我想知道为什么 Window 类没有可覆盖的 OnLoaded 方法。如果我想在加载 Window 时运行一些代码,我必须使用 Loaded 事件,即使这意味着我的类正在监听它自己。我不能总是把这段代码放在构造函数中,因为构造函数每个实例只发生一次,而 Load 事件发生零到多次。
    【解决方案2】:

    主要区别在于您确定何时调用基本代码的覆盖。消费事件时,您无法控制它。消费事件时,您本质上就是基础代码。

    这有时是一个重要的区别,因为如果有事件的消费者,但您需要在他们被调用之前完成工作,那么您需要覆盖。

    在这种情况下——可能差别不大。

    【讨论】:

      【解决方案3】:

      当您覆盖OnClosing 时,您可以使用CancelEventArgs 实现取消关闭的逻辑(参见MSDN)。另见an example

      万一你只是在窗口关闭前做一些工作,你不能影响关闭过程。

      【讨论】:

      • 我在我的测试中没有发现这是真的。在这两种情况下,该方法都有一个System.ComponentModel.CancelEventArgs e 参数。如果我在任一选项中的任何时候调用 e.Cancel = true;,当用户单击窗口右上角的红色 X 时,窗口都不会关闭。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 2022-07-21
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2013-10-17
      相关资源
      最近更新 更多