我有一个简单的问题,但解决方案似乎很棘手。我想在循环期间使用WPF控件画布进行打印;但是对于每次迭代,我都想用udpate画布控件。
如果我想在WPF中打印画布控件,我可以简单地调用
PrintDialog dialog = new PrintDialog();
dialog.PrintVisual(this.canvas, "");
它按预期打印到我的默认打印机。精彩。
但是,如果我想在循环中多次执行此操作并在每次迭代期间更新画布,则只打印循环的最后一次迭代。
private void methodName()
{
for (int i = 0; i < 2; i++)
{
updateTextBox(i.ToString());
PrintDialog dialog = new PrintDialog();
dialog.PrintVisual(this.canvas, "");
}
}
private void updateTextBox(string text)
{
txtTextBox.Text = text;
}
知道我需要做些什么来确保我得到2次打印输出,第一次使用txtTextBox.Text值为0,第二次输出值是否为1?
答案 0 :(得分:1)
我即将在我的应用程序中实现类似的东西,并发现我以前的答案不够好。对我来说问题是虽然画布在每次迭代中都会更新,但在发送到PrintVisual
之前它还没有自我渲染。令我惊讶的是,你打印了最后的迭代,我只得到了第一个。无论如何,这就是我使它工作的方式,基本上是在已经挂起的渲染操作之后排队打印命令:
for (int i = 0; i < 2; i++)
{
updateTextBox(i.ToString());
this.canvas.InvalidateVisual(); // Maybe not needed in your case
PrintDialog dialog = new PrintDialog();
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, (Action)delegate()
{
dialog.PrintVisual(this.canvas, "" + i);
});
}
是的,它与SalGad的答案和你所指的帖子有些相似(但不完全相同),但我无法对该答案发表评论,所以请尝试这个,它对我有用。
当对打印作业使用空描述时,我也遇到了打印消失的问题,因此+ i
。不知道这是一般问题,还是我的打印机设置。
我从this post得到了这个想法,它也提到了使用ViewBox的替代解决方案。
答案 1 :(得分:1)
行
我解决了。
我删除了所有调度程序对象方法,因此它在单个线程上运行。
要更新画布,我使用了canvas.UpdateLayout()方法。
我还确保在更新下一个画布(下一次迭代)之前已完成打印。
private void methodName()
{
for (int i = 0; i < 2; i++)
{
updateTextBox(i.ToString());
this.canvas.UpdateLayout();
PrintDialog dialog = new PrintDialog();
dialog.PrintVisual(this.canvas, "ABC");
dialog.PrintQueue.Refresh();
while (dialog.PrintQueue.NumberOfJobs != 0)
{
bool isQueued = false;
foreach (var job in dialog.PrintQueue.GetPrintJobInfoCollection())
{
if (job.Name == "ABC")
isQueued = true;
}
if (!isQueued)
break;
Thread.Sleep(500);
dialog.PrintQueue.Refresh();
}
}
}
private void updateTextBox(string text)
{
txtTextBox.Text = text;
}
我也可以刚刚完成thread.sleep(3000) - 因为它足够时间确保打印作业已经完成,但它也有点“充满希望”,我想要更安全的东西。
感谢大家的建议。
答案 2 :(得分:0)
如果您打算多次调用PrintVisual,则必须查看PrintDocument和DocumentPaginator。
答案 3 :(得分:0)
只是一个猜测,但是可能值得尝试RenderTargetBitmap
强制在每次迭代中渲染画布,然后使用该源创建一个Image,然后可以将其发送到PrintVisual
。有关代码示例,请参阅此文章:
答案 4 :(得分:0)
只是在这里拍摄,但是你可以尝试在每次for循环迭代的开始时刷新WPF画布控件吗?以下是代码段:
// declare this
public static class ExtensionMethods
{
private static Action EmptyDelegate = delegate() { };
public static void Refresh(this UIElement uiElement)
{
uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
}
}
// the loop
for (int i = 0; i < 2; i++)
{
updateTextBox(i.ToString());
PrintDialog dialog = new PrintDialog();
dialog.PrintVisual(this.canvas, "");
}
}
// update this method
private void updateTextBox(string text)
{
txtTextBox.Text = text;
txtTextBox.Refresh();
Thread.Sleep(500);
}
我从here
采购这个想法