从主窗体中的事件处理程序打开新窗体挂起应用程序

时间:2009-02-25 15:54:28

标签: c# winforms

我正在尝试在C#程序的主窗体中的事件处理程序中打开一个新窗体。事件处理程序被正确调用并打开新表单,但新表单被冻结,甚至最初都没有填充。

我可以在主窗体上创建一个按钮,并在单击按钮后创建新窗体,但是从事件处理程序完成后它无法正常工作。

事件处理程序不需要知道在它创建的表单上完成的任何事情的结果 - 它只需要创建它并且不用处。

我需要做什么?新表格需要独立于主表格运作。

这是我定义事件处理程序的地方:

ibclient.RealTimeBar += new EventHandler<RealTimeBarEventArgs>(ibclient_RealTimeBar);

这是事件处理程序代码:

void ibclient_RealTimeBar(object sender, RealTimeBarEventArgs e)
{
    FancyForm a_fancy_form = new FancyForm();
    a_fancy_form.Show();
}

通过点击按钮创建新表单可以正常工作:

private void button7_Click(object sender, EventArgs e)
{
    FancyForm a_fancy_form = new FancyForm();
    a_fancy_form.Show();
}

3 个答案:

答案 0 :(得分:2)

你可以发布事件处理程序代码吗?..也是在一个单独的线程中引发的事件然后是主要的ui?

编辑:
不确定实时栏的作用,但尝试检查表单上的invokerequired,这样你就可以在与主UI相同的线程上创建辅助表单..

void ibclient_RealTimeBar(object sender, RealTimeBarEventArgs e)
{
    if(this.InvokeRequired)
    {
        this.Invoke(((Action)() => ShowFancyForm()));
    }

    ShowFancyForm();
}

FancyForm a_fancy_form;
private void ShowFancyForm()
{
    if(null != a_fancy_form)return;

    a_fancy_form = new FancyForm();
    a_fancy_form.Show();
}

当然,这会使用一些脏快捷方式并假定为3.5,但您可以根据需要进行修改。

此外,我将FancyForm decleration移到了方法范围之外..再次根据您的需要进行调整。

答案 1 :(得分:2)

我有完全相同的问题,我使用了Quintin的代码,它现在工作正常....

为了使用框架2.0,我做了一些更改,这是我做的: 首先,我创建了一个委托,指向打开表单的方法:

public delegate void pantallazo();
pantallazo obj=new pantallazo(this.ShowFancyForm);

打开表单的方法与Quintin提供的方法相同:

smatiCliente a_fancy_form;   //smatiCliente  is the name of my new form class...
    private void ShowFancyForm()
    {
        if (null != a_fancy_form) return;
        a_fancy_form = new smatiCliente();
        this.Hide();
        a_fancy_form.Show();
    }

在我的programm的事件处理程序中,y进行了一些简单的更改:

 if(this.InvokeRequired)
                    {
                        this.Invoke(obj);
                    }
                    ShowFancyForm();

就是这样,它现在很有效。 Invoke方法执行适当的委托,因此现在在主UI下创建表单。

希望它有效,并且非常感谢Quintin!

答案 2 :(得分:0)

您知道事件处理程序中正在运行哪个线程吗?我相信它可能必须是主要的GUI线程才能工作。