1

簡単な問題がありますが、解決策は難しいようです。ループ中にWPFコントロールキャンバスを使用して印刷したい。しかし、反復ごとに、キャンバスコントロールを更新したいと思います。

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つのプリントアウトを確実に取得するために何をする必要があるか考えてみてください。1つ目はtxtTextBox.Textの値が0で、2つ目は値が1です。

4

5 に答える 5

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。それが一般的な問題なのか、それとも私のプリンタ設定の問題なのかわからない。

私はこの投稿からアイデアを得ました。これは、ViewBoxを使用した代替ソリューションについても言及しています。

于 2012-06-15T07:15:17.377 に答える
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)を実行することもできました。これは、印刷ジョブを確実に完了するのに十分な時間であったため機能しましたが、少し「希望」があり、より安全なものが必要でした。

皆様のご提案ありがとうございます。

于 2012-06-16T16:27:27.640 に答える
0

PrintVisualを複数回呼び出す場合は、PrintDocumentとDocumentPaginatorを調べる必要があります。

于 2012-06-14T14:41:56.527 に答える
0

推測ですがRenderTargetBitmap、各反復でキャンバスを強制的にレンダリングしてから、そのソースを使用してイメージを作成し、それをに送信することをお勧めしPrintVisualます。コード例については、この投稿を参照してください。

ビューポートの印刷

于 2012-06-14T14:52:03.333 に答える
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);
}

私はここからこのアイデアを調達しています

于 2012-06-14T15:01:57.133 に答える