Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 控件在第二次打开窗体时释放_C#_Winforms - Fatal编程技术网

C# 控件在第二次打开窗体时释放

C# 控件在第二次打开窗体时释放,c#,winforms,C#,Winforms,第一次从主窗体打开子窗体时,它会正常打开。如果我关闭子窗体的第一个实例,然后重新打开它,但是当我第一次尝试在OnPaint()方法之外调用CreateGraphics()时,会发生崩溃。我得到的异常是:“无法访问已处理的对象。对象名称:'MyControlClass'。” 我设置了断点来监视正在发生的事情。第一次关闭表单时,按预期调用Dispose()。当我启动表单时,第二次调用MyControlClass的构造函数,并且在异常发生之前不调用Dispose方法。在异常点时,此仍然有效。正因为如此

第一次从主窗体打开子窗体时,它会正常打开。如果我关闭子窗体的第一个实例,然后重新打开它,但是当我第一次尝试在
OnPaint()
方法之外调用
CreateGraphics()
时,会发生崩溃。我得到的异常是:“无法访问已处理的对象。对象名称:'MyControlClass'。”

我设置了断点来监视正在发生的事情。第一次关闭表单时,按预期调用Dispose()。当我启动表单时,第二次调用MyControlClass的构造函数,并且在异常发生之前不调用Dispose方法。在异常点
时,此
仍然有效。正因为如此,我想知道到底是不是
MyControlClass
的静态组件最终被处理掉了;不是实例对象

每次调用显示表单的按钮时,我都会创建表单的新副本。MyChildForm是my mt parentform持有的成员,还用于防止同时打开表单的多个副本

ShowMyForm()
{
    myChildForm = new myChildForm Form();
    myChildForm.FormClosed += myChildFormFormClosed;
    myChildForm.Show();
}

private void myChildFormFormClosed(object sender, FormClosedEventArgs e)
{
    myChildForm = null;
}
崩溃的代码行:MyControlClass继承自MyControlClassBase,后者又继承自MyControlClassBaseBase。这行代码由MyControlClassBase中的鼠标事件触发,并且在MyControlClassBaseBase中。之后的代码将获取MyControl的缓存图像,使用新创建的图形对象显示它,然后根据鼠标光标位置绘制覆盖图

Graphics g = CreateGraphics();

PS,因为我相信有人会问:问题中的rube goldberg是由于winforms中除了最琐碎的情况之外的任何情况下都是完全失败的假“透明性”以及MyControl类需要花费太长时间才能跟上鼠标光标的事实;但这完全是一个单独的问题。

关闭表单后,它将被释放,这意味着它的存在只是为了读取字段

如果要再次显示同一表单,请创建另一个实例,或者将其隐藏而不是关闭


因此,我们需要执行相同的步骤来再次展示:

f = new MyForm();
f.Show();
现在,您将得到一个全新的、完全相同的表单


但要在关闭时隐藏它,可能需要以下代码:

private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        e.Cancel = true;

        Hide();
    }
}
请注意,它将使用模态形式。(
ShowDialog();


(感谢Sorax)这也将适用于MDI儿童

能否显示一个最小的代码示例?共享处理MyControlClass实例化和关闭调用的代码将非常有帮助。@Sorax我已从父窗体添加了代码。子窗体中没有处理关闭/处理任何内容的自定义代码。代码段中的代码是正确的。但是,您没有发布实际失败的代码。Post或链接代码也会在我们的机器上失败;雕刻完整的演示器将是一个巨大的痛苦,因为我需要删除大量的内容并对其应用通用重命名。我相信这在MDI环境中也不适用于表单。我在第二次显示表单时创建了一个新的表单对象。因为您想重新显示表单,我想您可能需要保留一些数据。让我们假设您的数据位于
justAVariable
字段/属性中。它是可选的。您可以删除它。@Vercas否,第二次加载时是完全重新启动。我仍然不知道根本原因是什么,但切换到隐藏表单(并在重新显示时运行一些重新初始化代码)而不是处理/创建新副本修复了崩溃。
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        e.Cancel = true;

        Hide();
    }
}