【问题标题】:Generating Report in C# causing error在 C# 中生成报告导致错误
【发布时间】:2016-11-24 13:43:38
【问题描述】:

我正在使用后台工作程序在 C# 中生成报告,但出现此错误。

源码如下:

  • 我必须访问我的 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();
    }

有两个问题,首先从我得到答案的不同线程更新进度条,在后台工作人员导致问题之后的另一个调用表单实例,只需将变量放在后台工作人员启动异步之前并修复.

【问题讨论】:

  • 错误确实说明了一切。看看这里:link

标签: c# datagridview crystal-reports


【解决方案1】:

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

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

这是上面链接 parvee 上的一段代码,展示了如何做到这一点。

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

【讨论】:

  • 我仍然收到同样的错误,但现在进度条正在更新。我相信我正在从后台工作人员访问另一个表单实例,这也可能是原因。
  • 是backgroundWorker1.ReportProgress(5);抛出错误的行?请问该函数中的哪些对象是表单上的控件?
  • 我已经删除了 background1.ReportProgress,并使用了 UpdateProgress。此行抛出错误TR = Application.OpenForms.OfType&lt;Records&gt;().ElementAt(0);
  • 你能在调用后台工作者之前把它复制到一个类变量中吗?它失败了,因为它必须访问表单控件。
  • 谢谢。它现在已经修复了,基本上我在后台工作变量之前调用了表单变量并且它起作用了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 2010-09-18
  • 2023-03-04
  • 1970-01-01
  • 2018-11-04
  • 2014-04-16
相关资源
最近更新 更多