使用 WPF 进行 C# 打印

本文关键字:打印 进行 WPF 使用 | 更新日期: 2023-09-27 18:36:23

我的应用程序打印(到打印机)屏幕上显示的信息(使用 Canvas 控件)N 次。

该过程是

用户单击一个按钮(称为"打印")。
使用文本更新画布(通常来自数据库,但对于下面的代码,它是硬编码的)
打印到打印机
使用新文本更新画布(同样来自数据库,但对于下面的代码,它是硬编码的)打印到打印机

但是,我无法按照上述过程中的说明使其工作 - 打印机仅打印上次更新。

为了使这个问题可复制,我附上下面的代码

我的 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

尽管它已使用数字 1 迭代并更新了画布,但它永远不会打印(打印空白页)。

任何想法我需要做什么才能打印每个画布?尽管我可以通过显示消息框来使其工作,但它违背了自动化的目的。

编辑:我现在收到来自打印机的错误消息 - "另一台计算机正在使用打印机。根据其他网站的说法,我必须等到一项工作完成,然后第二项工作将自动开始,但遗憾的是,它永远不会开始。

使用 WPF 进行 C# 打印

使用 PrintDialog

对话框 = new PrintDialog(); 内部为循环 使用此函数

 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);
            }
            ));   
        }
    }

答案(对不起,代码与问题不完全相同,但它非常简单,应该很容易理解。谢谢大家。

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; }
    }
}

你的UpdateText方法都是错误的。每次调用该方法时,都会在文本块中创建一个新字符串。 因此,您将看到的只是对例程的最后一次调用。

相反,您应该附加到文本而不是替换文本。

BeginInvoke 返回 DispatcherOperation。如果在 for 循环中继续之前调用 Wait 它,则在执行第一次打印之前,文本框将不会更新。