我发现了一些问题,但没有什么可以帮助我的逻辑。我有以下代码(显示不是全部因为它太多了):
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。每隔几行我创建一个新的ChartArea,将这些行中的一些值绑定到Series并将其绑定到ChartArea。我实际上正在将ChartAreas绘制到我的Chart Control中。每两个ChartAreas我打印控件,清理它,并绘制下两个ChartAreas(最后有12个 - 所以6次绘制到图表控件)。这有效,但我希望实现以下目标: 我想为每个图表控件添加一个新页面到我的打印事件,这样我最后有6页,然后将其打印到一个文件(pdf)。不知何故,由于e.HasMorePages属性,它会进入printPage事件的不定式循环。这如何与图表一起使用? 非常感谢你!
答案 0 :(得分:1)
您最好让PrintDocument
班级驱动您的数据,而不是尝试驾驶PrintDocument
。 PrintDocument类将引发PrintPage
事件,我们的任务是为该单个页面提供数据。数据会转到PrintPageEventArgs
中提供的Graphics
实例。如果我们要打印另一个页面,我们确保HasMorePages
为真,printdocument实例将再次调用PrintPage
,我们提供下一页的数据等。当我们没有更多数据而不是想要打印更多页面,我们将HasMorePages
设置为false。
根据您的代码,我创建了以下示例,我希望该示例适用于您的案例。
我认为DataTable中的Rows是确定是否需要打印以及打印多少页面的主要来源。如果它不是基于此,您可以为不同的集合/数组创建一个枚举器,机制保持不变。
// 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;
}
我有两个辅助方法,一个用于创建带有行的DataTable,另一个用于生成一些有趣的图表。
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));
}
}
当我使用预览控件运行时,这就是我得到的: