2

私のアプリケーションは、画面に表示されている情報を (Canvas コントロールを使用して) N 回 (プリンターに) 印刷します。

プロセスは

ユーザーがボタン (印刷と呼ばれる) をクリックします。
Canvas をテキストで更新します (通常はデータベースから取得しますが、以下のコードではハードコーディングされています)
Print to printer
新しいテキストで Canvas を更新します (再びデータベースから取得しますが、以下のコードではハードコーディングされています) Print to printer

ただし、上記のプロセスで説明したようにこれを機能させることはできません。プリンターは最後に行われた更新のみを印刷します。

この問題を再現できるようにするために、以下のコードを同封します

マイ XAML

<Window x:Class="WpfApplication4.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Canvas Margin="0,0,0,88" Name="canvas1">
        <TextBlock Text="Hello World" Name="TextBlock1" />
    </Canvas>
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="0,245,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</Window>

そして私のコードビハインド

using System;
using System.Windows;
using System.Printing;
using System.Windows.Threading;
using System.Windows.Controls;

namespace WpfApplication4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        PrintDialog dialog = new PrintDialog();
        for (int i = 1; i < 3; i++)
        {
            //showing this message box fixes the issue
            //MessageBox.Show("01");
            updateTextblock(i);

            //use the dispatcher object to ensure all renders and databinding are completed before sending to print   
            DispatcherOperation disO;
            disO = Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(delegate
            {
                print(dialog);
            }
            ));   
            disO.Wait()
        }
    }

    private void print(PrintDialog dialog)
    {
        //select printer auotmatically
        PrintQueue queue = new LocalPrintServer().GetPrintQueue("Canon MG160 series WS");
        //assign the printer  
        dialog.PrintQueue = queue;

        dialog.PrintVisual(canvas1, "");
    }

    private void updateTextblock(int i)
    {
        TextBlock1.Text = "Number " + i.ToString();
    }
}
}    

印刷されるのはナンバー2だけです

Number 1 でキャンバスを繰り返し更新しましたが、印刷されません (空白のページが印刷されます)。

各キャンバスが印刷されるようにするために必要なことは何ですか? メッセージボックスを表示することで機能させることはできますが、自動化の目的を無効にします。

編集:プリンターからエラーメッセージが表示されます-「別のコンピューターがプリンターを使用しています。」他の Web サイトによると、1 つのジョブが終了するまで待たなければならず、その後 2 つ目のジョブが自動的に開始されますが、悲しいことに、決して開始されません。

4

4 に答える 4

1

答え(申し訳ありませんが、コードは質問とまったく同じではありませんが、とてもシンプルでわかりやすいはずです。ありがとうございました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;


namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < 2; i++)
            {
            result res = null;     
            if (i == 0)
            res = new result { Comments = "First Time Round" };

            if (i == 1)
                res = new result { Comments = "Total hard type" };

            Dispatcher.Invoke(DispatcherPriority.Loaded, new Action(delegate
                {   
                    this.DataContext = res;
                }
            ));

            System.Threading.Thread.Sleep(500);

            Dispatcher.Invoke(DispatcherPriority.Loaded, new Action(delegate
            {
                PrintDialog dialog = new PrintDialog();
                dialog.PrintVisual(this.canvas1, "");
            }
        ));
            System.Threading.Thread.Sleep(500);

            }
        }
    }

    class result
    {
        public string Comments { get; set; }
    }
}
于 2012-06-15T07:50:29.117 に答える
1

PrintDialog ダイアログを使用 = new PrintDialog(); for ループ内 この関数を使用します

 private void button1_Click(object sender, RoutedEventArgs e)
    {

        for (int i = 1; i < 3; i++)
        {
           PrintDialog dialog = new PrintDialog();
            //showing this message box fixes the issue
            //MessageBox.Show("01");
            updateTextblock(i);

            //use the dispatcher object to ensure all renders and databinding are completed before sending to print   
            Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(delegate
            {
                print(dialog);
            }
            ));   
        }
    }
于 2012-06-05T18:34:41.220 に答える
0

BeginInvoke はDispatcherOperationを返します。for ループを続行する前に Wait を呼び出すと、最初の印刷が実行されるまで、テキスト ボックスは更新されません。

于 2012-06-05T21:04:39.753 に答える
0

あなたの UpdateText メソッドはすべて間違っています。メソッドを呼び出すたびに、テキストブロックに新しい文字列を作成しています。その結果、ルーチンへの最後の呼び出しだけが表示されます。

代わりに、テキストを置き換えるのではなく、テキストに追加する必要があります。

于 2012-06-05T18:31:45.267 に答える