WPF - 在循环期间打印

本文关键字:打印 循环 WPF | 更新日期: 2023-09-27 18:37:24

我有一个简单的问题,但解决方案似乎很棘手。我想在循环期间使用 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?

WPF - 在循环期间打印

我即将在我的应用程序中实现类似的东西,发现我之前的答案还不够好。对我来说的问题是,尽管画布在每次迭代中都会更新,但在发送到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.不知道这是一个通用问题,还是只是我的打印机设置有关。

我从这篇文章中得到了这个想法,其中还提到了使用 ViewBox 的替代解决方案。

OK

我解决了。

我删除了所有调度程序对象方法,使其在单个线程上运行。

为了更新画布,我使用了画布。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) - 这有效,因为它有足够的时间确保打印作业完成,但它也有点"希望",我想要更安全的东西。

感谢大家的建议。

如果您要多次调用PrintVisual,则必须查看PrintDocument和DocumentPaginator。

只是一个猜测,但可能值得尝试RenderTargetBitmap在每次迭代中强制渲染画布,然后使用该源创建一个图像,然后将其发送到PrintVisual。有关代码示例,请参阅此帖子:

打印视口

只是在这里试一试,但你能尝试在每次 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);
}

我从这里采购这个想法