在构造函数期间关闭表单

时间:2010-06-18 07:39:34

标签: c# winforms constructor

是否可以在构造函数执行时关闭表单(或者只是在此阶段停止显示)?

我有以下代码:

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);
    }
}

但这似乎没有帮助。有谁能告诉我解决这个问题,好吗?也许是一种检查表单以查看它是否仍然存在的方法?

9 个答案:

答案 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()的情况下打开主表单。

相关问题