【问题标题】:How to stop timer event when child form closes in MDI project如何在 MDI 项目中关闭子窗体时停止计时器事件
【发布时间】:2014-01-25 08:30:48
【问题描述】:

我不是 Windows 窗体的常客,但总体上还是在 C# 方面做得更好。我正在为一个comp开发一个项目。编。类,它是一个允许多个子窗体的 MDI 窗体。

这是我的泡菜, 我在父表单上有一个计时器;勾选时,处理两种标签方法..一种用于计算文本文档中的字符,另一种用于显示缩放级别。

当子窗口打开时,我可以让计时器触发并处理我的事件,但是当我关闭窗口时,我试图弄清楚如何以某种方式停止计时器。 我尝试了 form.closure 事件,并尝试在完成后禁用计时器,但这没有帮助。

该项目是一个文本编辑器,对象的名称 ID 为“文档”。当对象被 Disposed 时,我自然会得到一个异常,但我想在这种情况发生之前禁用计时器。

“无法访问已释放的对象”

这是我调用子窗体实例的 New() 方法..

        void New()
      {
          // Generate a new form from scratch
          TextEditorChild = new Form();  // Declare a variable containing a new Form method
          TextEditorChild.Text = "Document " + count.ToString();  // Text Property - also gets the forms order number
          TextEditorChild.Icon = Properties.Resources._new_doc_icon;  // Use our own icon
          TextEditorChild.MdiParent = this;  // Ensure we are using the original form as the parent form
          Document = new RichTextBox();  // Call a new RichTextBox object
          Document.Multiline = true;  // Yes, a multiline textbox
          Document.Dock = DockStyle.Fill;  // Ensure that the textbox fills the new window
          TextEditorChild.Controls.Add(Document);  // Apply our controls to the child window
          TextEditorChild.Show();  // Display the window
          count++;  // Add this window to a potnetial list of windows, should multiple be opened all at once
          timer.Enabled = true;
      }

这是我的计时器偶数处理程序...

       private void timer_Tick(object sender, EventArgs e)
    {
            charCount.Text = "Characters in the current document: " + Document.TextLength.ToString();
            zoom.Text = Document.ZoomFactor.ToString();
    }

【问题讨论】:

  • 您打开了多个 TextEditorChild 还是只打开了一个?
  • 它只抛出一个异常。实际上,我发布的代码根本不允许计时器开始。我的第一个刺是创建和 IF 语句和 ' if (TextEditorChild == null) { return; } else { // 方法 } ' 这有效,但是当我关闭子窗口时,我又收到了消息。

标签: c# winforms


【解决方案1】:

你可以添加

TextEditorChild.FormClosing += new FormClosingEventHandler(Close);

在new()方法中


private void Close(object sender, FormClosingEventArgs e)
{
    timer.Enabled = false;
}

并在下面添加这个,作为一个新方法


这样当表单关闭时,它会停止计时器,然后退出表单

【讨论】:

  • 明白了。我可能已经尝试过类似的方法,但我不确定在方法中使用什么类型的参数。谢谢!
【解决方案2】:

就在您启用计时器的行之前添加以下代码:

        var tec = TextEditorChild;
        FormClosingEventHandler closing = null;
        closing = (s, e) =>
        {
            tec.FormClosing -= closing;
            if (--count == 0)
            {
                timer.Enabled = false;
            }
        };
        tec.FormClosing += closing;

当所有窗口都关闭时,这应该会停止计时器。我将模块级别 TextEditorChild 捕获为 tec 以确保在您打开新的子窗口时引用不会更改。

我假设您正在减少其他地方的 count 值,因此您需要调整逻辑以使其正常工作,但这应该是一个好的开始。

【讨论】:

  • 我无法使用该方法。不过,我喜欢你这样做,因为我有一个类似的想法,即当我的子窗口计数降至零时简单地禁用计时器。
  • 我将继续以不同的方式尝试这种方法,因为这也是我处理它的理想方式。我也感谢您的意见。
  • 我尝试了上面的代码,如果我启用了计时器,但当我关闭一个新的子窗口时,我仍然遇到同样的异常。
  • @codeman061988 - 我会在timer.Enabled = false 行上放一个断点,看看它是否被调用。如果没有,请在tec.FormClosing -= closing 行上查看它是否达到了那么远。
  • 我今天早上用这种方法玩了一会儿,当(--count == 0) 时我无法上班。有趣的是,当我将运算符更改为 < 1.. ..我想知道它是否仅适用于第一个实例。虽然我的New() 方法适用于每个新实例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-22
相关资源
最近更新 更多