繁体   English   中英

C#创建/关闭多个表单(线程)-Crystal Report Viewer

[英]C# Creating/Closing Multiple Forms (Threads) - Crystal Report Viewer

我已经解决了6个小时的问题,但仍然无法解决。 我希望你能帮助我。

我正在研究一个与Crystal-Report-Engine有关的项目(SAP,.NET Framework 4.0中的最新版本,32位C#应用程序)。 基本上,它像这样工作:

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

问题:现在,我正在创建一个新的ReportForm(我自己的类),该类是Windows.Form中带有CrystalReportViewer的派生类。 ReportForm使用传递的参数将crystalReportViewer-Object的ReportSource设置为先前创建的ReportDocument。 ->显示表单时,正在加载Crystal Report Viewer。

问题1:当Crystal Report Viewer加载报表时,我仍然希望能够访问我的主窗体(有时可能需要5到6分钟的时间)-例如,在上一个报表仍在运行时创建其他报表加载。 仅当我为该新表单创建线程时才有可能-但这(有时)会导致ContextSwitchDeadlock,因为我必须创建一个新线程,这将创建一个新的GUI控件(ReportForm)。

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

基本上看起来像这样(简短版本):

/* pass parameters to reportDocument */
ReportForm reportForm = new ReportForm(reportDocument);
reportForm.Show();

在ReportForm中:

crystalReportViewer.ReportSource = this.reportDocument;

你有什么想法?

最佳,Cylence

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

对于为Crystal Report Viewer创建新线程的每个人:当心!

解决问题-SAP

这是一个常规解决方案:

/* 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;
    }
}

最佳,Cylence

谢谢! 这为我解决!

为了简化上面的代码:

 /* 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;
     }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM