我有一个订单。订单完成后,我使用线程将订单通过电子邮件发送给供应商。Thread 用于防止订单导出为 pdf 并发送时系统挂起。
问题:一旦威胁完成且没有错误,我想在 MDIParent Toolstripstatuslabel 上放置一条消息,以确认订单已发送。但我收到一个错误:“System.NullReferenceException:对象引用未设置为对象的实例”。我可能错了,指的是子窗口在关闭时在父窗体上设置了工具条状态标签引用,因此威胁无法再访问它。我知道简单的解决方案是使用 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 时,我的 Parent 表单将始终处于打开状态。所以我基本上遍历所有打开的表单以找到对活动 MdiParent 实例的引用,然后将其传递回调用者。然后在线程中使用以下代码。
MDIParent1 fm = null;
if ((fm = (MDIParent1)IsFormAlreadyOpen(typeof(MDIParent1))) != null)
{
fm.Toolstripstatuslabel1.Text = "Order No:" + strOrderNo + " was successfully send to " + strEmails;
}
我仍在寻找更好的方法,但现在这可行。