2

ReportViewer コントロールと、いくつかの問題を引き起こしているカスタム印刷ジョブ ワークフローを使用しています。私のコードは次のようになります。

        ids.ForEach(delegate(Guid? guid)
            {
                var details = items.Where(e => e.guid == guid);

                var ds = new ReportDataSource("Form", details);
                ReportViewer.LocalReport.DataSources.Clear();
                ReportViewer.LocalReport.DataSources.Add(ds);
                ReportViewer.RefreshReport();

            });

RefreshReport()最終的に呼び出されると、そのRenderingCompleteイベントが発生し、そのイベントで印刷ジョブをキューに入れるロジックがあります。

        if (DisplayPrintDialog) ReportViewer.PrintDialog();
        else
        {
            var document = new PrintDocument(ReportViewer.LocalReport);
            document.PrinterSettings = ReportViewer.PrinterSettings;
            document.Print();
        }
        DisplayPrintDialog = false;

問題は、RenderingCompleteイベントが発生する前に ForEach ループの実行が終了するため、ループのパスごとに RenderingComplete イベントが発生するまで ForEach ループをブロックする方法が必要なことです。これについての良い方法は何ですか?

4

2 に答える 2

0

Spike のスニペットはシグナルの良い例ですが、(彼ら自身の過ちではなく) 私の問題を解決するには不十分であり、彼らの考えを適応させるだけでもコードが必要以上に複雑になります。

この問題を熟考した後、ReportViewer コントロールとこの特定のプロセスを分離することができました。つまり、この特定のワークフローで ReportViewer コントロールの必要性 (したがって、シグナル伝達の必要性) を取り除き、もう少し単純なものを思いついたということです。

foreach (var item in guids)
{
     var details = items.Where(e => e.guid == item);
     var report = new LocalReport
         {
            ReportPath = [Path]
         };

     var ds = new ReportDataSource("Form", details);
     report.DataSources.Clear();
     report.DataSources.Add(ds);

     printingInvoked = ProcessPrintJob(report);

     if (!printingInvoked) break;
}

これは元のコードに似ていますが、主な違いは、LocalReport のインスタンスを作成し、ReportViewer の LocalReport プロパティの代わりにそれを直接操作していることです。次に、実際に印刷ジョブを処理します。

if (DisplayPrintDialog)
{
     if (PrintWindow.ShowDialog() != DialogResult.OK)
     {
          return false;
     }   
}

var document = new PrintDocument(report);
document.PrinterSettings = PrintWindow.PrinterSettings;
document.Print();

DisplayPrintDialog = false;
return true;

この場合、PrintWindow は PrintDialog 型で、PrintDocument は System.Drawing.Printing.PrintDocument の拡張であり、実際の RDLC ファイルを処理します。もちろん、これが行っていることは、最初にユーザーにプリンターの設定を求め、次にn 個のハイドレートされたレポートをプリンターに送信することだけです。

助けてくれてありがとう!

于 2013-05-31T17:54:22.837 に答える