2016-11-24 6 views
0

バックグラウンドワーカーを使用してC#でレポートを生成していますが、このエラーが発生しています。エラーが発生するC#でレポートを生成

enter image description here

ソースコードを次のように

  • を、私はそれのデータにアクセスするために私のDataGridViewのレコードにアクセスする必要があります。
  • 私のdatagridviewに小さなウィンドウが開き、そこから日付を入力してレポートを生成してから、データテーブルに変換してデータファイルに書き込んでレポートを生成します。

グローバル変数

// This is the form where the data lies, I'm accessing it's instance. 
      Records TR = new Records(); 
// This is the form where report will be displayed. 
      TReportDisplay TRD = new TReportDisplay(); 
// This is the report. 
      Treport treport1 = new Treport(); 

    private void button1_Click(object sender, EventArgs e) 
     { 
      // FIXED HERE - 1 
      // FIXED - 2 IN THE ANSWER BELOW. 
     // Accessing my DataGridView Form Instance. 
      TR = Application.OpenForms.OfType<Records>().ElementAt(0); 
      treport1.SetDataSource(TR.ds); 
      TRD.crystalReportViewer2.ReportSource = treport1; 

      backgroundWorker1.RunWorkerAsync(); 
     } 

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 

     try 
     { 

      TRD.crystalReportViewer2.ReportSource = treport1; 
      ParameterFieldDefinitions Parameters; 
      ParameterFieldDefinition Parameter; 
      ParameterValues Values = new ParameterValues(); 
      ParameterDiscreteValue DiscreteValue = new ParameterDiscreteValue(); 

      DiscreteValue.Value = dateTimePicker1.Text; 
      Parameters = treport1.DataDefinition.ParameterFields; 
      Parameter = Parameters["fromdate"]; 
      Values = Parameter.CurrentValues; 
      Values.Clear(); 
      Values.Add(DiscreteValue); 
      Parameter.ApplyCurrentValues(Values); 
      DiscreteValue.Value = dateTimePicker2.Text; 
      Parameters = treport1.DataDefinition.ParameterFields; 
      Parameter = Parameters["todate"]; 
      Values = Parameter.CurrentValues; 
      Values.Add(DiscreteValue); 
      Parameter.ApplyCurrentValues(Values); 

     } 
     } 
     catch (Exception ex) { MessageBox.Show(ex.Message.ToString(), "Message"); }; 
    } 

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 

    } 

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     TRD.ShowDialog(); 
    } 

背景労働者が問題を引き起こした後、私は答え、別の呼び出しフォームのインスタンスを持っているため、別のスレッドからのすべての更新プログレスバーの最初の2つの問題がありましたが、バックグラウンドワーカーが非同期で開始して固定される前に変数を置くだけです。

+0

エラーは本当にすべてを言います。ここを見て:[リンク](http://stackoverflow.com/questions/7609839/accessing-a-forms-control-from-a-separate-thread) – parvee

答えて

1

エラーメッセージは、コントロールを更新する唯一の方法は、コントロールが実行されているスレッド経由であることを示しています。現在、別のスレッド(バックグラウンドワーカー用スレッド)で実行しています。

SO Invoke(Delegate)の別の質問については、このリンクの例をご覧ください。あなたは基本的にあなたが正しいスレッド上にあるかどうかをチェックするUIを更新するために呼び出すことができるメソッドを持っている必要があります。

これはあなたがこれを行う方法を示しているリンクパヴェ上にあったコードスニペットです。

public void UpdateProgress(int percentComplete) 
{ 
    if (!InvokeRequired) 
    { 
     ProgressBar.Value = percentComplete; 
    } 
    else 
    { 
     Invoke(new Action<int>(UpdateProgress), percentComplete); 
    } 
} 
+0

と私はこれをどのように使用するのですか?クロススレッドにはごめんなさい。 – Patrick

+0

私はまだ同じエラーが表示されていますが、進行状況バーが更新されています。私はバックグラウンドワーカーから別のフォームインスタンスにアクセスしている可能性があると考えています。 – Patrick

+0

それはbackgroundWorker1.ReportProgress(5)ですか?エラーをスローする行?どの機能のオブジェクトがフォーム上のコントロールですか? –

関連する問題