Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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_Constructor - Fatal编程技术网

C# 在构造过程中关闭窗体

C# 在构造过程中关闭窗体,c#,winforms,constructor,C#,Winforms,Constructor,是否可以在构造函数执行时关闭窗体(或在此阶段停止显示) 我有以下代码: public partial class MyForm : Form { public MyForm() { if (MyFunc()) { this.Close(); } } } 它在Main()中抛出ObjectDisposedException,如下所示: 我尝试过这样检查我表单的结果: static vo

是否可以在构造函数执行时关闭窗体(或在此阶段停止显示)

我有以下代码:

public partial class MyForm : Form
{        
    public MyForm()
    {
        if (MyFunc())
        {
            this.Close();
        }
    }
}
它在Main()中抛出ObjectDisposedException,如下所示:

我尝试过这样检查我表单的结果:

static void Main()
{            
    ...

    MyForm frm = new MyForm();
    if (frm != null)
    {
        // Following line errors
        Application.Run(frm);
    }
}

但这似乎没有帮助。有谁能告诉我怎么办吗?也许有一种方法可以检查表单是否仍然存在?

能否将MyFunc设置为静态?然后做一些类似的事情:

static void Main() 
{             
    ... 
    if (MyForm.MyFunc())
    {
        Application.Run(new MyForm()); 
    }
} 
这基本上可以让您控制是否构造表单?

当您对表单调用Close()时,它在内部处理表单并释放任何托管资源。执行此操作时:

Application.Run(new MyForm());
您可能会得到一个ObjectDisposedException。您需要做的是通过属性设置窗体的可见性:

Application.Run(new MyForm() { Visible = false });

只需确保在构造函数中删除对Close()的调用,甚至将属性赋值也移动到那里。

唯一可以做的事情是在构造函数中设置一个标志来关闭它,然后在显示的
事件中关闭它。当然,如果您正在这样做,那么移动代码以确定是否应该首先在那里关闭它是有意义的。

以下操作非常有效:

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

无法从表单的构造函数调用
Close
,因为它将对尚未创建的表单调用
Dispose
。若要在构造后关闭表单,请将匿名事件处理程序分配给在首次显示表单之前关闭表单的:

public partial class MyForm : Form
{
    public MyForm()
    {
        if (ShouldClose())
        {
            Load += (s, e) => Close();
            return;
        }

        // ...
    }

    // ...
}

我发现在“Load”事件中添加一个处理程序更好,因为这样就根本不会显示对话框。在“显示”事件中,您可能会短暂地看到对话框打开然后关闭,这可能会让人困惑:

public partial class MyForm : Form
{        
    public MyForm()
    {
        if (MyFunc())
        {
            this.Load += MyForm_CloseOnStart;
        }
    }

    private void MyForm_CloseOnStart(object sender, EventArgs e)
    {
        this.Close();
    }
}

我认为在构造函数中关闭窗体是不明智的。如果这样做,表单的用户将不知道是否显示对话框

以下代码将是非常正常的使用:

// in the parent form:
public void ShowMyForm()
{
    MyForm form = new MyForm();
    form.propertyA = ...;
    from.propertyB = ...;
    DialogResult dlgResult = form.ShowDialog(this);
    ProcessDialogResult(dlgResult);
}
如果在构造函数中决定是否应显示表单,则必须在构造后添加代码,以决定是否调用ShowDialog以及是否处理对话框结果

此外,您确定更改属性永远不会影响窗体是否显示吗?在未来的变化之后呢

在施工期间,尚未显示/打开模板。因此,我担心
Close()
无法实现您的期望

整洁的方法是以加载的形式在构造函数中执行您想要执行的检查。为表单加载添加事件处理程序,并在事件处理程序中执行检查。使用属性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.
    }
}
但是,在事件处理程序中为表单加载调用Close()将不起作用,因为只有在加载完成后才能正确调用
Close()

因此,不应调用
Close()
,而应
BeginInvoke
Close()函数,以便在加载完成后调用
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())
    }
}

如果您希望您的窗口永远不会被看到(没有闪烁的窗口会打开一瞬间然后消失):

虽然
Show(…)
有2个重载,
ShowDialog(…)
也有2个重载。
不适用于通过
Application.Run()
打开的主窗体。但谁会这么做呢?除此之外,还有一种方法可以在不使用
应用程序的情况下打开主窗体。Run()

环境。退出(…)
对我有效(没有窗口闪烁):


+1,只需将所示内容替换为Load(负载),以确保无闪烁,您就有了winner@Dialecticus:谢谢。完成!这给了我一个错误:“执行CreateHandle()时无法调用Value Close()”太棒了!谢谢(:Christian,这真是太好了!谢谢!这应该是公认的答案,当前公认的答案会编译,但会出现运行时错误。这也是我最喜欢的答案,因为有比取消构造函数更好的方法来实现这一点。在我的情况下,主要是关于我在Program.cs中初始化的主窗体,所以如果我不想让它通过d、 然后我就不在我的新对象上调用“Application.Run”。这比使用事件之类的方法来防止闪烁要容易得多。嗯,这似乎是
这一点。在DialogResult设置为
DialogResult.Abort
后,取消加载()不会被调用。如果删除DialogResult分配行,则会成功调用它。
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())
    }
}
public new void Show()
{
    if (MyFunc())
        base.Show();
    else
        ; // dispose or whatever
}
public partial class MyForm : Form
{        
    public MyForm()
    {
        if (weShouldClose)
        {
            Environment.Exit(0);
        }
    }
}