【问题标题】:How do I add Dispose functionality to a C# UserControl?如何将 Dispose 功能添加到 C# UserControl?
【发布时间】:2008-10-03 16:04:17
【问题描述】:

我有一个实现 UserControl 的类。在 .NET 2005 中,会在 MyClass.Designer.cs 部分类文件中自动创建一个 Dispose 方法,如下所示:

  protected override void Dispose(bool disposing)
  {
     if (disposing && (components != null))
     {
        components.Dispose();
     }
     base.Dispose(disposing);
  }

如果我想添加自己的 Dispose 功能,我应该把它放在哪里?由于生成了这个文件,我不想在这里添加代码并冒着被吹走的风险。

【问题讨论】:

    标签: c# user-controls dispose


    【解决方案1】:

    所有Component 类都实现Disposed 事件。您可以为该事件添加事件处理程序并清理其中的内容。

    例如,在您的UserControl 中,您可以添加以下方法:

    private void OnDispose(object sender, EventArgs e)
    {
        // do stuff on dispose
    }
    

    并在构造函数(或Load 事件处理程序)中添加以下行:

    Disposed += OnDispose;
    

    【讨论】:

    • @Jacob Seleznev:不知道为什么没有更多人对此表示赞同。也许他们没有看到?我认为 Disposed 事件是向任何支持它的类添加处置功能的正确方法。
    • +1 - 我同意 supercat 的观点,这比当前接受的答案更好。
    • 我相信,事件应该从课外处理,而不是从内部处理。我想,任何人都可能用他自己的覆盖事件处理程序并阻止资源被释放。处理控件内部事务的正确方法是重写基类提供的适当虚拟方法。
    • 如果您需要对控件的组件(例如 BindingSource)执行逻辑,则使用 Disposed 事件将无法解决问题 - 此时组件已被释放。控制 Dispose 方法似乎是在这里完全控制流程的唯一方法。在我的情况下,有必要调用 BindingSource.Clear() 来强制内部生成的 BindingList 分离 PropertyChanged 事件处理程序并防止内存泄漏。
    • 因为void Dispose(bool disposing)中的disposing参数传递的信息不能通过Disposed事件访问(或者至少我找不到;Control.Disposing成员的文档没有表示它共享disposing 参数的语义)。因此,只有非托管资源可以通过Disposed 事件安全地处置。
    【解决方案2】:

    在这种情况下,我将生成的Dispose 方法移动到主文件并扩展它。 Visual Studio 尊重这一点。

    另一种方法是使用部分方法 (C# 3.0)。

    【讨论】:

    • Designer 文件中的 Dispose 方法可以扩展为包括对部分方法的调用,该方法可以在主文件中实现。
    • 由于 MyClass.Designer.cs 文件已经是部分文件,您可以简单地将所需的逻辑添加到已生成的 Dispose 方法中。 Visual Studio 不会在创建方法后覆盖该方法,因此您可以安全地对其进行修改。
    【解决方案3】:

    我相信在这种情况下,代码生成器会尊重您的代码。把它放在代码隐藏中应该是安全的。

    【讨论】:

    • 是的,它不在文件的“生成的代码”部分。
    【解决方案4】:

    在 VS 2005(和 2008)中,您可以更新 Dispose 方法,当您从设计器编辑控件时,它不会被删除。

    【讨论】:

      【解决方案5】:

      如果需要,您可以将其从 .designer.cs 文件中移出并移到主 .cs 文件中。正如已经说过的,它不会被覆盖。

      【讨论】:

        【解决方案6】:

        您只需在用户控件继承的组件类中重载 public void Dispose() 方法即可。

        确保您将调用传递给基本方法并在功能上进行处置,否则您将破坏功能,除非您完全实现它

        【讨论】:

        • 这是个好主意。对于每个 Microsoft 实现的 System.Windows.Forms.Control 子类,您需要对 Dispose(bool disposing) 进行更多控制,您可以将其子类化并在那里覆盖 Dispose,添加对一些虚拟 DisposeCore 方法的调用,如 another question’s answer 中所述。您可以读取disposing 参数的值并且 仍然避免编辑设计器文件。双赢。
        【解决方案7】:

        我认为最干净的方法是让您的控件订阅它自己的 Disposed() 事件并在那里进行清理。

        【讨论】:

          【解决方案8】:

          UserControl 有一个 Unloaded 事件,可用于清理,

          【讨论】:

          • 这个问题是关于一个WinForms UserControl,它没有Unloaded事件。也许您的意思是 WPF 或 Silverlight 控件?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-06-09
          • 1970-01-01
          • 1970-01-01
          • 2015-10-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多