C# 关闭后处理表单
我在C#中遇到了一个新问题,即开合形式 我的问题是如何处理关闭后的表单 这是我的密码: Program.cs:C# 关闭后处理表单,c#,winforms,forms,dispose,C#,Winforms,Forms,Dispose,我在C#中遇到了一个新问题,即开合形式 我的问题是如何处理关闭后的表单 这是我的密码: Program.cs: static class Program { public static Timer timer; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefaul
static class Program
{
public static Timer timer;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
timer = new Timer { Interval = 1000};
timer.Start();
Application.Run(new Form1());
}
}
表格1.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.ShowDialog();
/// I've tried Dispose() method . but didn't work
}
}
表格2.cs:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
Program.timer.Tick += timer_Tick;
Close();
// I've tried Dispose() method instead of Close() but didn't work
}
private int count = 0;
void timer_Tick(object sender, EventArgs e)
{
count++;
if (count == 5) MessageBox.Show("");
}
}
编辑:
我的问题是:为什么当form2关闭时,消息框在5秒后显示 编辑:这个问题原来是关于处置的 首先,Dispose与垃圾收集无关。发生以下情况:
好的,第一部分:
使用(){}
块会更好,但这应该可以:
private void button1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.ShowDialog();
/// I've tried Dispose() method . but didn't work
form.Dispose(); // should work
}
如果没有,请描述“不起作用”
这很奇怪,但我假设这是问题的人工代码 您的全局程序.Timer现在存储对Form2实例的引用,并将阻止收集该引用。它不会阻止它被释放/关闭,因此您的计时器将持续触发一个关闭的窗体,这通常会失败并导致其他问题
Program.timer.Tick-=timer\u Tick代码>
在使用后处理
表单
的最简单、最可靠的方法是将用法放在using块中
using (Form2 form = new Form2()) {
form.ShowDialog();
}
C#中的using块是一个基本上将上述内容扩展为以下代码的构造
Form2 form;
try {
form = new Form2();
...
} finally {
if ( form != null ) {
form.Dispose();
}
}
ShowDialog()将窗体显示为模式对话框。这意味着在表单关闭之前,呼叫不会返回。请注意,在模式对话框上单击“关闭X”并不会关闭窗体,它只是将其隐藏。我猜这就是让你困惑的地方。 如果希望form1中的代码继续执行而不是阻塞,则应调用Show()而不是ShowDialog()。单击X时,非模态将关闭 如果您确实需要一个阻塞模式对话框,则应使用其他答案中所述的using块围绕表单。
构建模式对话框时,通常会添加“OK”按钮或类似按钮,并将表单的AcceptButton属性设置为该按钮,以允许用户通过按enter键关闭表单。同样,您可以添加“取消”按钮并设置CancelButton属性以捕获Esc键。
在两个按钮上添加一个单击处理程序,相应地设置窗体的DialogResult属性并调用Close()。也许我读错了问题,但我认为先生们需要知道,要关闭作为form2.ShowDialog()打开的窗体(比如form2),需要在form2中设置form2.DialogResult。关闭表单并返回结果只需设置该成员。这是一个老问题,但它涉及到一些关于对象如何工作的有趣问题。形式本质上是一个对象。同一类的所有对象共享相同的方法,但每个对象都有自己的数据。这是什么意思?这意味着,关闭或处理对象不会从内存中释放/删除/删除任何代码。只有数据。所有这些都是关于对象的,不管是什么语言 现在,特别是关于您的代码。让我们检查一行
Program.timer.Tick+=timer\u Tick代码>可以。这将在Form对象中向timer对象提供一个指向函数的指针。因此,现在,无论您对表单对象做什么,计时器对象都将继续调用该函数。计时器对象不关心窗体,甚至不知道窗体对象的存在。它只关心您将指针传递到的函数。就计时器对象而言,此函数是一个独立函数
Form.Close()做什么?Close()处理表单使用的资源,也就是标记表单控件进行垃圾回收,除非使用ShowDialog显示表单。在这种情况下,必须手动调用Dispose()
不用说,如果关闭/处理表单清除了内存中的函数,计时器对象将具有无效指针,程序将在5秒后崩溃。为什么要在垃圾收集器为您执行此操作之前处理表单(假设没有对剩余表单的引用)?“它不起作用”是什么意思意思是?是否引发异常?窗口是否消失?@Lazarus:问得好。+1对于建议使用语句,可能想给他举个例子。亲爱的Henk Holterman,删除计时器滴答事件是一个好的解决方案,但我的问题是,为什么消息框会显示窗体已处理的时间?@Mironline:为什么不应该?Ti也不应该mer或MessageBox都不需要该表单。尝试在timer_Tick中设置控件属性,将出现异常。在秒块中,form2必须在访问之前初始化。如果初始化,则它永远不等于null。我尝试过,但消息框在5秒后显示。
Form2 form;
try {
form = new Form2();
...
} finally {
if ( form != null ) {
form.Dispose();
}
}