2016-11-13 4 views
0

私はこれにいくつかの問題を発見しましたが、私のロジックに役立つものは何も見つかりませんでした。今、私が何をしたいのかPrintPageチャートコントロールを印刷中にイベントが無限ループに留まる

public int AreaCounter { get; set; } = 0; 
public PrintDocument pd { get; set; } 

public void PrintCharts(DataTable dt) 
{ 
     foreach (DataRow row in dt.Rows) 
     { 
      //after a couple of rows - here is code for creating 
      //a new chartArea and binding the points to the series 
      //plus binding that series to the area 

      if(// two chartAreas have been created with each one having a chart) 
      { 
       PrintChartControl(); 
      } 
      AreaCounter++; 
     } 
} 

    private void PrintChartControl() 
    { 
    pd.PrintPage += pd_PrintPage; 
    pd.Print(); 
    } 

    private void pd_PrintPage(object sender, PrintPageEventArgs e) 
    { 
     if (AreaCounter < 11) //12 ChartAreas have to be created 
      e.HasMorePages = true; 
     else 
      e.HasMorePages = false; 

     var myRec = e.MarginBounds; 
     Container.chart1.Printing.PrintPaint(e.Graphics, myRec); 
    } 

:私は、コードを(それがあまりにも多くなるので、すべてではない示す)以下きたDataTableを通じて Iループを。いくつかの行ごとに、私は新しいChartAreaを作成し、この行からいくつかの値をSeriesにバインドし、これをChartAreaにバインドします。私はChartAreasをChartコントロールに実際に描画しています。 2つのChartAreasごとに、コントロールを印刷して、それをクリーニングし、次の2つのChartAreasを描画します(最後に12があり、チャートコントロールに6倍の描画)。これは動作しますが、次のようにしたいと考えています: 最後に6ページがあるように、すべてのChart Control用の新しいページを印刷イベントに追加して、これを1つのファイル(pdf)に印刷します。何とかして、e.HasMorePagesプロパティのためにprintPageイベントの不定ループに入ります。これはチャートとどのように機能しますか? ありがとうございます!

+1

? –

+0

申し訳ありません。コードを編集しました – Canox

+0

PrintPageイベントハンドラ内で、印刷ロジックとループの制御を行う必要があります。 「この私の答え」(http://stackoverflow.com/a/32514337/578411)が役立つかどうかを見てください。 – rene

答えて

1

PrintDocumentをドライブしようとする代わりに、PrintDocumentクラスでデータをドライブすることをお勧めします。 PrintDocumentクラスはPrintPageイベントを発生させます。その1ページのデータを提供するのは私たちの仕事です。データはPrintPageEventArgsで提供されているGraphicsインスタンスに送られます。 HasMorePagesが真であることを確認した別のページを印刷する場合は、printdocumentインスタンスはPrintPageを再度呼び出し、次のページのデータを提供します。データがなくなり、印刷されるページがもうない場合は、 HasMorePagesをfalseに設定します。

コードに基づいて、私はあなたのケースに当てはまると考えられる次の例を作成しました。

DataTableの行が、印刷する必要があるかどうか、および印刷する必要のあるページ数を決定する主なソースであると仮定しました。それに基づいていない場合、別のコレクション/配列の列挙子を作成することはできますが、メカニズムは変わりません。

// the reference to the enumerator for the DataRows 
IEnumerator rows; 

private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
{ 
    var dataTable = Load(); 
    rows = dataTable.Rows.GetEnumerator(); 
} 

private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) 
{ 
    // no rows, no glory 
    if (rows == null) return; 

    // keep track of stuff 
    var chartsOnthisPage = 0; 
    var yPos = 20f; 

    // loop for what needs to go on this page, atm it prints 2 charts 
    // as long as there are rows 
    // the enumerator is moved to the next record ... 
    while ((e.HasMorePages = rows.MoveNext())) 
    { 
     // ... get hold of that datarow 
     var currentRow = (DataRow)rows.Current; 

     // print 
     e.Graphics.DrawString(currentRow[0].ToString(), Font, Brushes.Black, 0, yPos); 
     // keep track where we are 
     yPos = yPos + 40; 

     // do what ever is need to print the chart fro this row 
     GenerateChart(currentRow); 
     // print the chart 
     chart1.Printing.PrintPaint(e.Graphics, new Rectangle(0, (int)yPos, 200, 200)); 
     // position tracking 
     yPos = yPos + 200; 
     // optionaly break here if we reached the end of the page 
     // keep track 
     chartsOnthisPage++; 
     if (chartsOnthisPage > 1) break; // HasMorePages is set 
    } 
} 

private void printDocument1_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
{ 
    // clean up; 
    rows = null; 
} 

は、私は2つのヘルパー・メソッド、1行でデータテーブルを作成するために、もう1つは、いくつかの興味深いチャートを生成することがあります。

private DataTable Load() 
{ 
    var dt = new DataTable(); 
    dt.Columns.Add("chart"); 

    for(int r=0; r<10; r++) 
    { 
     var rw = dt.NewRow(); 
     rw[0] = Guid.NewGuid().ToString("N"); 
     dt.Rows.Add(rw); 
    } 
    return dt; 
} 

Random rnd = new Random(); 
private void GenerateChart(DataRow row) 
{ 
    chart1.Series.Clear(); 
    chart1.Series.Add("data"); 
    var mx = rnd.Next(rnd.Next(10) + 3); 
    for (int x = 0; x < mx; x++) 
    { 
     chart1.Series[0].Points.Add(x, rnd.Next(100)); 
    } 
} 

私は、プレビューコントロールでこれを実行すると、これは私が得るものです:あなたは `AreaCounter`をインクリメントん

enter image description here

関連する問題