我正在尝试创建一个窗口,该窗口会在PDF文档的页面上绘制一张卡片。
我的想法是收到collection
(应该在卡片上绘制的项目),然后浏览它们,并为每个项目加载到UniformGrid
(到给出真实卡片的印象),捕获屏幕图像并将其绘制到PDF文档页面。
到目前为止一切顺利。
以下是我尝试的内容:
(以下代码已添加到窗口的Loaded
事件处理程序中)
PdfDocument document = new PdfDocument();
// This is just an example
int[][] items = new int[10][];
// Fill the matrix
foreach (int[] array in items)
{
Dispatcher.Invoke(() =>
{
// uGrid is an UniformGrid
uGrid.Children.Clear();
foreach (int id in array)
{
Border child = null;
// Create child element and add it to the Uniform Grid
uGrid.Children.Add(child);
}
});
Dispatcher.Invoke(new Action(() =>
{
// Draws an image of 'this' to the PDFDocument 'document'
PdfHelper.DrawPictureOfControlToPdf(document, this);
// DispatcherPriority.ContextIdle here is responsible for executing the DrawPicture method only after the uGrid has been redrawed
}), DispatcherPriority.ContextIdle, null);
}
// This will save the PDF on your documents folder
document.Save(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyTestPDF.pdf"));
此外,可以找到生成的PDF(在调试时以及何时没有 - 请参阅下面的问题)here
上述代码在调试模式 时效果很好 。
调试时:代码运行没有错误,使用正确的页数创建PDF,并在其上正确绘制卡片。
如果没有:代码运行没有错误,PDF是使用正确的页数创建的,但不会在其上绘制。
我认为导致此问题的原因是以下代码中的DispatcherPriority.ContextIdle
:
Dispatcher.Invoke(new Action(() =>
{
PdfHelper.DrawPictureOfControlToPdf(document, this);
}), DispatcherPriority.ContextIdle, null);
它应该表明Action
必须仅在UniformGrid
完成重绘时(或者在Dispatcher处理完之后,更确切地说)之后运行。但显然这只适用于调试模式。
有人知道如何解决这个问题吗?
如果没有,我有没有想到的替代方案?
@EDIT
我不认为这很重要,但我使用PDFSharp生成/处理PDF
答案 0 :(得分:3)
删除代码中的所有Dispatcher.Invoke
(这里没有做任何好事),然后调用
this.UpdateLayout();
在调用PdfHelper.DrawPictureOfControlToPdf(document, this);
之前强制重绘当前控件。