首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#创建/关闭多个窗体(线程)-水晶报表查看器

C#创建/关闭多个窗体(线程)-水晶报表查看器
EN

Stack Overflow用户
提问于 2014-08-14 00:49:22
回答 2查看 2K关注 0票数 0

我已经为一个问题做了6个小时了,我还是想不出答案。我希望你能帮我。

我正在从事一个与水晶报告引擎( .NET Framework4.0,32位C#应用程序上的最新版本)有关的项目。基本上,它是这样工作的:

我正在打开我的主表单,它动态地显示特定报告文件(.rpt)的所有参数。输入参数值后,应用程序将执行一些语法检查,并将参数传递给ReportDocument。

问题是:现在我正在创建一个新的ReportForm (我自己的类),它是一个带有CrystalReportViewer的Windows.Form派生类。该ReportForm将crystalReportViewer对象的ReportSource设置为先前创建的带有传递参数的ReportDocument。当窗体出现时,->水晶报表查看器正在加载。

问题1:在水晶报表查看器加载报表时,我仍然希望能够访问我的主表单(有时可能需要5-6分钟)--例如,在前一个报表仍在加载时创建一些其他报告。这只有在我为这个新表单创建一个线程时才有可能,但这(有时)会导致一个ContextSwitchDeadlock,因为我必须创建一个新的线程,它正在创建一个新的GUI-控件( ReportForm)。

问题2:如果我不创建一个新线程并启动新的ReportForm (例如使用myNewReportForm.Show() ),那么我必须等到报表加载之后才能访问我的主表单(直到报告完全加载)。下一个问题是,我无法关闭/退出/关闭我的应用程序,因为线程仍然在加载报告--我还必须等待,直到加载了报告。但是,我希望能够随时关闭应用程序(主窗体和所有ReportForms)。

基本上看上去是这样的(简写):

代码语言:javascript
复制
/* pass parameters to reportDocument */
ReportForm reportForm = new ReportForm(reportDocument);
reportForm.Show();

在ReportForm中:

代码语言:javascript
复制
crystalReportViewer.ReportSource = this.reportDocument;

你有什么想法吗?

最好的,塞伦斯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-14 14:35:43

问题终于解决了。所以这就是我的解决方案:

对于正在为水晶报表查看器创建新线程的每个人:小心!

问题解决- SAP

以下是一个通用的解决方案:

代码语言:javascript
复制
/* In Main Form */

            /*...*/

     ThreadStart threadStart = delegate() { reportThreadFunction(reportDocument); };
     Thread reportThread = new Thread(threadStart);

     /* Setting the ApartmentState to STA is very important! */
     reportThread.SetApartmentState(ApartmentState.STA);
     reportThread.Start();
}

         /* ... */

private void reportThreadFunction(ReportDocument reportDocument)
{
     ReportThread rt = new ReportThread(reportDocument);
     newReportForm = rt.Run();
     Application.Run(newReportForm);
     newReportForm.Show();
}


/* Class ReportThread */
public class ReportThread
{
    ReportDocument reportDocument;
    CrystalReportViewer crv;
    Template template;

    public ReportThread(ReportDocument reportDocument)
    {
        this.reportDocument = reportDocument;
    }

    public ReportForm Run()
    {
        ReportForm rf = new ReportForm(reportDocument);
        return rf;
    }
}

最好的,塞伦斯

票数 1
EN

Stack Overflow用户

发布于 2018-02-23 12:06:37

谢谢!这是我的决心!

只是为了简化上面的代码:

代码语言:javascript
复制
 /* In Main Form */

 /*...*/
 ThreadStart threadStart = delegate({reportThreadFunction(reportDocument);};
 Thread reportThread = new Thread(threadStart);

 /* Setting the ApartmentState to STA is very important! */
 reportThread.SetApartmentState(ApartmentState.STA);
 reportThread.Start();
 }

 private void reportThreadFunction(ReportDocument reportDocument)
 {
     //Create and Start the form
     Application.Run(new ReportThread(reportDocument));
 } 


 /* Class ReportThread */
 /* A form whith a CrystalReportViewer inside*/
 public partial class ReportThread : Form
 {
     public CrystalReportViewer crv; //initiated in partial class off form

     public ReportThread(ReportDocument reportDocument)
     {
        InitializeComponent();
        CrystalReportViewer.ReportSource = reportDocument;
     }
 }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25298438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档