在结束表格

时间:2017-06-29 15:23:33

标签: c# multithreading winforms mdiparent toolstripstatuslabel

我有一张订单。订单完成后,我会使用一个线程将订单通过电子邮件发送给供应商。线程用于防止系统在订单导出为pdf并发送时挂起。

问题:一旦威胁完成且没有错误,我想在MDIParent Toolstripstatuslabel上放置一条消息,以确认订单已发送。但是我得到一个错误:" System.NullReferenceException:对象引用未设置为对象的实例"。我可能错了,指的是子窗口在关闭时在父窗体上放置了too​​lstripstatuslabel引用,因此威胁无法再访问它。我知道简单的解决方案是使用MessageBox来确认一切顺利...但为什么如果你可以做到优雅的话容易?

所以我的问题:如何从威胁中引用父表单中的控件?我试着看看调用,但不确定如何实现它或者它实际上是正确的方向。

编辑:

来自childform的代码

public partial class frm_n_order : Form
{
     .
     .

private void bProcess_Click(object sender, EventArgs e)
{
     .
     .
     .

    new Thread(new ThreadStart(delegate
    {
        fExportOrder(strOrderNo);
        fSendMailv2(strPlant, strSupCode, strOrderNo);                                
    })).Start();

    this.close();
}

private void fExportOrder(string strOrderNo)
{
    //export order to pdf
}

private void fSendMailv2(string strPlant, string strSupCode, string strOrderNo);
{
    // get pdf
    // get email address

    try
    {
        // send email
        ((MDIParent1)MdiParent).tsslMain.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails;  //here I need to find a different way of accessing the Toolstripstatuslabel in the parent form
    }
    catch
    {
        MessageBox.Show("Email did not send");
    }
}

}

编辑:

好的,所以花了一天多的时间试图弄清楚如何使用Invoke,我意识到虽然在使用线程时这似乎是一种很好的做法,但这不是我的答案。我的问题直接与子窗体关闭处理所有控件有关,因此它失去了对MdiParent的引用。为了解决这个问题,我做了以下几点:

在我的孩子班上,我补充道:

public static Form IsFormAlreadyOpen(Type FormType)
{
    foreach (Form OpenForm in Application.OpenForms)
    {
    if (OpenForm.GetType() == FormType)
        return OpenForm;
    }
    return null;
 }

我不认为这是最优雅的解决方案,但理论是当我需要访问Toolstripstatuslabel时,我的父表单将始终打开。所以我基本上遍历所有打开的表单,找到对活动MdiParent实例的引用,然后将其传递回调用者。在线程中,我然后使用以下代码。

 MDIParent1 fm = null;
 if ((fm = (MDIParent1)IsFormAlreadyOpen(typeof(MDIParent1))) != null)
 {
      fm.Toolstripstatuslabel1.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails;
 }

我仍然在寻找更好的方法,但现在这种方法很有效。

1 个答案:

答案 0 :(得分:0)

好的,所以花了一天多的时间试图弄清楚如何使用Invoke,我意识到虽然在使用线程时这似乎是一种很好的做法,但这不是我的答案。我的问题直接与子窗体关闭处理所有控件有关,因此它失去了对MdiParent的引用。为了解决这个问题,我做了以下几点:

在我的孩子班上,我补充道:

public static Form IsFormAlreadyOpen(Type FormType)
{
    foreach (Form OpenForm in Application.OpenForms)
    {
    if (OpenForm.GetType() == FormType)
        return OpenForm;
    }
    return null;
 }

我不认为这是最优雅的解决方案,但理论是当我需要访问Toolstripstatuslabel时,我的父表单将始终打开。所以我基本上遍历所有打开的表单,找到对活动MdiParent实例的引用,然后将其传递回调用者。在线程中,我然后使用以下代码。

 MDIParent1 fm = null;
 if ((fm = (MDIParent1)IsFormAlreadyOpen(typeof(MDIParent1))) != null)
 {
      fm.Toolstripstatuslabel1.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails;
 }

我仍然在寻找一种更好的方法,但现在这种方法很有效。