2016-11-24 19 views
0

我使用后台工作器在C#中生成报告,但我收到此错误。在C#中生成报告导致错误

enter image description here

源代码如下:

  • 我要访问我的datagridview记录来访问它的数据。
  • 在我的datagridview中打开一个小窗口,要求用户输入日期并生成报告,然后访问我的datagridview转换为数据表写入XML文件并生成报告。

全局变量

// 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(); 
    } 

有两个问题,第一,从一个不同的线程,我得到的答案全部更新进度条,经过后台工作的另一个电话形式的实例是造成问题,只需将变量放在后台工作者启动异步并修复之前。

+0

错误真的说明了一切。看看这里:[链接](http://stackoverflow.com/questions/7609839/accessing-a-forms-control-from-a-separate-thread) – parvee

回答

1

错误消息告诉您更新控件的唯一方法是通过控件运行的线程。您目前正在使用不同的线程(后台工作人员)。

查看此链接中关于SO Invoke(Delegate)上的其他问题的示例。你基本上应该有一个你可以调用的方法来更新UI,它可以检查它是否在正确的线程上,以及它是否得到正确的线程来调用它。

这是上面给出的链接parvee上的一段代码,显示了如何执行此操作。

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);引发错误的行?该功能中的哪些对象是表单上的控件? –