是否可以在构造函数执行时关闭表单(或者只是在此阶段停止显示)?
我有以下代码:
public partial class MyForm : Form
{
public MyForm()
{
if (MyFunc())
{
this.Close();
}
}
}
在Main()中抛出ObjectDisposedException,这里:
static void Main()
{
...
// Following line errors
Application.Run(new MyForm());
}
我已经尝试过检查MyForm的结果:
static void Main()
{
...
MyForm frm = new MyForm();
if (frm != null)
{
// Following line errors
Application.Run(frm);
}
}
但这似乎没有帮助。有谁能告诉我解决这个问题,好吗?也许是一种检查表单以查看它是否仍然存在的方法?
答案 0 :(得分:82)
无法从表单的构造函数中调用Close
,因为它将在尚未创建的表单上调用Dispose
。要在构造后关闭窗体,请为Load
event指定一个匿名事件处理程序,以便在第一次显示之前关闭窗体:
public partial class MyForm : Form
{
public MyForm()
{
if (ShouldClose())
{
Load += (s, e) => Close();
return;
}
// ...
}
// ...
}
答案 1 :(得分:20)
你唯一能做的就是在构造函数中设置一个标志来关闭它,然后在Shown
事件中关闭它。当然,如果你这样做,那么移动代码以确定它是否应该首先在那里关闭是有意义的。
答案 2 :(得分:17)
以下效果很好:
public partial class MyForm : Form
{
public MyForm()
{
if (MyFunc())
{
this.Shown += new EventHandler(MyForm_CloseOnStart);
}
}
private void MyForm_CloseOnStart(object sender, EventArgs e)
{
this.Close();
}
}
答案 3 :(得分:8)
当您在表单上调用Close()时,它在内部处理表单并释放任何托管资源。当你这样做时:
Application.Run(new MyForm());
您可能会遇到ObjectDisposedException。您需要做的是通过属性设置表单的可见性:
Application.Run(new MyForm() { Visible = false });
只需确保在构造函数中删除对Close()的调用,或者甚至在那里移动属性赋值。
答案 4 :(得分:3)
你可以让MyFunc静态吗?然后做类似的事情:
static void Main()
{
...
if (MyForm.MyFunc())
{
Application.Run(new MyForm());
}
}
这基本上可以让你控制是否要构建表单吗?
答案 5 :(得分:3)
我发现在'Load'事件中添加一个处理程序更好,因为这样对话框根本不会显示。使用“已显示”事件,您可能会暂时看到对话框打开然后关闭,这可能会造成混淆:
public partial class MyForm : Form
{
public MyForm()
{
if (MyFunc())
{
this.Load += MyForm_CloseOnStart;
}
}
private void MyForm_CloseOnStart(object sender, EventArgs e)
{
this.Close();
}
}
答案 6 :(得分:2)
我认为在构造函数中关闭表单是不明智的。如果您这样做,表单的用户将不知道是否显示ShowDialog。
以下代码非常正常使用:
// in the parent form:
public void ShowMyForm()
{
MyForm form = new MyForm();
form.propertyA = ...;
from.propertyB = ...;
DialogResult dlgResult = form.ShowDialog(this);
ProcessDialogResult(dlgResult);
}
如果您在构造函数中决定是否应该显示Form,则必须在构造之后添加代码以决定是否调用ShowDialog以及是否处理对话结果。
此外,您确定更改属性永远不会影响表单是否显示?还有未来的变化吗?
在施工期间,表格尚未显示/打开。所以我担心Close()
没有达到你的期望。
简洁的方法是在Form_Load中的构造函数中执行您想要进行的检查。为表单加载添加事件处理程序,并在事件处理程序中执行检查。使用属性DialogResult表示您决定不显示表单。
private void FormMain_Load (object sender, EventArgs e)
{
if (FormShouldNotLoad())
{
this.DialogResult = System.Windows.Forms.DialogResult.Abort;
Close();
// Warning, this does not work, see below, (but we're almost there!)
}
}
代码的用户可以检查对话框的结果:
// in the parent form:
public void ShowMyForm()
{
MyForm form = new MyForm();
form.propertyA = ...;
from.propertyB = ...;
DialogResult dlgResult = form.ShowDialog(this);
switch (dlgResult)
{
case System.Windows.Forms.DialogResult.Abort:
ProcessFormNotLoaded();
break;
case System.Windows.Forms.DialogResult.OK:
ProcessFormOk();
break;
// etc.
}
}
但是,在form-load的事件处理程序中调用Close()将不起作用,因为只有在Load完成后才能正确调用Close()
。
因此,您应该Close()
Close()函数,而不是调用BeginInvoke
,因此在加载完成后将调用Close
函数:
private void FormMain_Load (object sender, EventArgs e)
{
if (FormShouldNotLoad())
{
this.DialogResult = System.Windows.Forms.DialogResult.Abort;
// invoke the Close function after Load completed
this.BeginInvoke(new MethodInvoker( () => this.CancelLoading())
}
}
答案 7 :(得分:2)
Environment.Exit(...)
正在为我工作(没有窗口闪烁):
public partial class MyForm : Form
{
public MyForm()
{
if (weShouldClose)
{
Environment.Exit(0);
}
}
}
答案 8 :(得分:0)
如果您希望自己的窗口永远不会被看到
(没有闪烁的窗口瞬间打开然后消失):
public new void Show()
{
if (MyFunc())
base.Show();
else
; // dispose or whatever
}
虽然Show(...)
有2个重载,ShowDialog(...)
也有2个重载
不适用于通过Application.Run()
打开的主表单。但无论如何谁会这样做?除了还有一种方法可以在不使用Application.Run()
的情况下打开主表单。