2015-10-03 56 views
1

我在我的主菜单上有一个名为“Active Reports”的菜单项。当用户选择要打印的报告时,我在单独的线程中关闭水晶报表浏览器。用户可以打开多个报告查看器并且我想跟踪它们。主要是这个菜单列表将允许用户点击报告,并且如果报告在处理报告数据时运行时间过长,我可以在该线程上发起中断以取消正在运行的报告。当每个报表查看器关闭时,我将从菜单列表中删除它。我有一个名为ReportThreadClass的类,它跟踪当前正在运行的每个报表以及它所属的线程。在线程中关闭报告之后,我想更新“活动报告”菜单项并将正在运行的报告的名称添加到活动报告列表中。这是我创建线程和ReportThreadClass的代码。从多个线程访问菜单c#

public class ReportThreadClass 
{ 
    public Thread Thread { get; set; } 
    public bool AbortFlag { get; set; } 
    public string ReportName { get; set; } 
    public int ReportId { get; set; } 
} 

    public void RunReport(UAReport report) 
    { 
     Thread staThread = new Thread(r => ReportDocumentThread((UAReport) r)); 
     staThread.SetApartmentState(ApartmentState.MTA); 
     staThread.Start(report); 
    } 

    public void ReportDocumentThread(UAReport report) 
    { 
     var service = new UAReportService(report); //class that creates the report document that will be passed to the report viewer. 
     ReportDocument reportDocument = service.CreateReportDocument(); 
     string reportDesc = report.ReportDesc; 

     object args = new object[2] {reportDocument, reportDesc}; 

     var staThread = new Thread(new ParameterizedThreadStart(ReportViewerThread)); 

     int nextReportId; 
     if (!Program.MainForm.ReportThreads.Any()) 
      nextReportId = 0; 
     else 
     { 
      nextReportId = Program.MainForm.ReportThreads.Count() + 1; 
     } 

     ReportThreadClass reportThread = new ReportThreadClass(); 
     reportThread.Thread = staThread; 
     reportThread.ReportName = reportDesc; 
     reportThread.AbortFlag = false; 
     reportThread.ReportId = nextReportId; 

     Program.MainForm.ReportThreads.Add(reportThread); //list of all active reports running. 
     Program.MainForm.BuildActiveReportsMenu(); //how do i do this from thread. 

     staThread.SetApartmentState(ApartmentState.STA); 
     staThread.Start(args); 
     staThread.Join(100); 

    } 

    public void ReportViewerThread(object args) 
    { 
     Array argArray = new object[3]; 
     argArray = (Array) args; 
     ReportDocument reportDocument = (ReportDocument) argArray.GetValue(0); 
     string reportDesc = (string) argArray.GetValue(1); 

      try 
      { 
       ReportViewerForm form = new ReportViewerForm(reportDocument, reportDesc); 
       form.BringToFront(); 
       form.ShowDialog(); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 

    } 

因此,我在一个线程中关闭一个新报表后如何创建“活动报表菜单”。基本上,我将通过ReportThreads列表循环,并将活动报告添加到“活动报告”菜单项。 ReportThreads列表是在主窗口中声明和维护的。我可以通过Program.MainWindow访问它。

回答

0

如果我正确理解你,你想改变你的表单从另一个线程。要做到这一点,你可以使用Invoke方法,像这样:

Program.MainForm.Invoke(() => Program.MainForm.BuildActiveReportsMenu()); 
+0

是什么'Program.MainForm'? – Eser

+0

OP访问他的表单的方式。可能是一个领域或财产,我直接从他的代码中拿走它。 – georch

+0

这只是访问状态栏,菜单和工具栏的主窗口的钩子。好的,我在代码中添加了这行代码,以及如何在主窗口类中创建委托。 –