我有一张订单。订单完成后,我会使用一个线程将订单通过电子邮件发送给供应商。线程用于防止系统在订单导出为pdf并发送时挂起。
问题:一旦威胁完成且没有错误,我想在MDIParent Toolstripstatuslabel上放置一条消息,以确认订单已发送。但是我得到一个错误:" System.NullReferenceException:对象引用未设置为对象的实例"。我可能错了,指的是子窗口在关闭时在父窗体上放置了toolstripstatuslabel引用,因此威胁无法再访问它。我知道简单的解决方案是使用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;
}
我仍然在寻找更好的方法,但现在这种方法很有效。
答案 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;
}
我仍然在寻找一种更好的方法,但现在这种方法很有效。