2017-06-29 11 views
0

私は初心者ですので、私と一緒に裸にしてください。私の複雑な問題には簡単な解決策があるかもしれません。C#winforms - 閉じたスレッドのスレッドでToolstripstatuslabelを更新する

私は注文フォームを持っています。注文が完了したら、スレッドを使用して注文をサプライヤに電子メールで送ります。スレッドは、注文がpdfにエクスポートされて送信されている間、システムがハングするのを防ぐために使用されます。

問題:脅威がエラーなしで完了した後、MDIParent Toolstripstatusラベルにメッセージを送信して、注文が送信されたことを確認します。しかし、私はエラーが発生します: "System.NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていません"。私は間違っている可能性がありますが、子ウィンドウは閉じたときに親フォーム上にtoolstripstatuslabel参照を配置したので、脅威はそれ以上アクセスできなくなります。簡単な解決策は、すべてがうまくいっていることを確認するためにMessageBoxを使用することです...しかし、あなたはそれをエレガントにすることができますか?

私の質問:親フォームのコントロールを脅威からどのように参照できますか?私は、呼び出しを見てみましたが、実装する方法や実際に正しい方向であるかどうかはわかりません。

EDIT: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"); 
    } 
} 

} 

EDIT:

オクラホマので、呼び出しを使用する方法を把握しようと1日以上過ごした後、私はそれながら実現スレッドで作業するときは良い練習のように思えますが、それは私の答えではありません。私の問題は、子フォームの閉じ方に直接関係しているので、MdiParentへの参照が失われるようにすべてのコントロールが破棄されます。私が追加私の子クラスで

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

私はそれが最もエレガントなソリューションであると思ういけないが、理論はときに私私の親フォームが常に開いているということである問題を解決するために、私は次のことをやりましたToolstripstatusラベルにアクセスする必要があります。だから私は基本的に開いているフォームをループしてアクティブなMdiParentインスタンスへの参照を見つけ出し、呼び出し元に戻します。スレッドでは、次のコードを使用します。

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

私はまだ優れたアプローチを探していますが、今のところこれが機能します。

+1

終了すると、実際に使用しようとしている時点で、ユーザーはどのようにアップデートを見ますか? – Will

+1

@彼は、彼がちょうど閉じたものの*親ウィンドウのツールストリップステータスラベルを変更することを意味すると思います。私たちは実際のコードを見ることができますか?正確に間違っていることを理解するのはちょっと難しいです。 –

+0

@ user1339124あなたの説明からの解決策を試してみると、親ウィンドウへの参照をスレッドに渡してから、 'App.Current.Dispatcher.Invoke(()=> {/ *ここで状態ラベルを更新するスレッドに渡された参照を使用する* /}); –

答えて

0

これで、Invokeの使い方を理解しようとしていた1日以上を過ごした後、スレッドで作業するときのように思えるのですが、それは私の答えではありません。私の問題は、子フォームの閉じ方に直接関係しているので、MdiParentへの参照が失われるようにすべてのコントロールが破棄されます。私が追加私の子クラスで

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

私はそれが最もエレガントなソリューションであると思ういけないが、理論はときに私私の親フォームが常に開いているということである問題を解決するために、私は次のことをやりましたToolstripstatusラベルにアクセスする必要があります。だから私は基本的に開いているフォームをループしてアクティブなMdiParentインスタンスへの参照を見つけ出し、呼び出し元に戻します。スレッドでは、次のコードを使用します。

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

私はまだ優れたアプローチを探していますが、今のところこれが機能します。

関連する問題