【问题标题】:Real size WPF controls for printing用于打印的真实尺寸 WPF 控件
【发布时间】:2013-08-13 19:56:01
【问题描述】:

我目前正在开发一个应用程序,用户可以在其中动态地在画布上创建/移动 TextBlock。一旦他们将 TextBlocks 定位到他们想要的位置,他们就可以按下打印按钮,这将导致 ZPL 打印机打印当前显示在屏幕上的内容。

ZPL 命令是通过从每个 TextBlock 中获取以下值来构建的:

  • XPosition = Canvas.Left
  • YPosition = Canvas.Right
  • 文本 = 文本

但是,我找不到让打印输出类似于屏幕显示的方法。我猜这是因为 Canvas.Left 和 Canvas.Right 的值与打印机 DPI 不匹配。

这是我目前使用的转换(因为我认为 Canvas.Left = 1 表示 1/96 英寸)(画布的左上角是 0,0)

public double GetZplXPosition(UIElement uiElement)
{
    int dpiOfPrinter = 300;
    double zplXPosition = (Canvas.GetLeft(uiElement) / 96.0) * dpiOfPrinter;
    return zplXPosition;
}

我可以在“实际大小”中显示控件吗?使用的纸张将始终为 A5(8.3 英寸 x 5.8 英寸)。

我想过在画布周围使用一个视图框,它的宽度和高度设置为 830 x 580(A5 的比例正确),但这并没有帮助。

有什么建议吗??

谢谢

【问题讨论】:

    标签: c# wpf printing dpi zpl


    【解决方案1】:

    代替你正在做的事情,拍摄整个画布的“屏幕截图”并打印出来。

    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    
    namespace ImageProcessing
    {
        public class ImageProc
        {
            public RenderTargetBitmap GetImage(UIElement source)
            {
                double actualHeight = source.RenderSize.Height;
                double actualWidth = source.RenderSize.Width;
    
                if (actualHeight > 0 && actualWidth > 0)
                {
                    RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)actualWidth, (int)actualHeight, 96, 96, PixelFormats.Pbgra32);
                    VisualBrush sourceBrush = new VisualBrush(source);
    
                    DrawingVisual drawingVisual = new DrawingVisual();
                    DrawingContext drawingContext = drawingVisual.RenderOpen();
                    drawingContext.DrawRectangle(sourceBrush, null, new Rect(0, 0, actualWidth, actualHeight));
                    drawingContext.Close();
    
                    renderTarget.Render(drawingVisual);
                    return renderTarget;
                }
                else
                    return null;
            }
        }
    }
    

    【讨论】:

    • 这是个好主意,但我可能需要为用户添加添加条形码的功能。 Zebra 打印机具有板载条码生成功能,这是质量目的所必需的。对不起,应该提到这一点。我在您的 RenderTargetBitmap() 方法中看到 dpiX 和 dpiY 的值 96,这是因为 wpf 中屏幕的 dpi 是必不可少的 96?
    • 我很久以前从VS文档中得到了代码,所以96 dpi来自那里。
    • 很公平。这实际上看起来是捕获打印预览类型图像的一种非常好的方法。
    • 仅注意:如果您使用此代码,请确保设置要捕获的元素的背景,即使仅设置为透明。忽略这一点可能会导致屏幕截图看起来很奇怪。
    【解决方案2】:

    我刚刚完成了某种形式的表单设计器的编写。这是我所做的:

    我有一个用户控件,大小为 850x1100 单位(WPF 单位,但认为是“信纸大小的纸张 :)”),并且大小是固定的。我将控件放在我想要的任何地方,我在ViewBox 内的窗口中显示此控件,它为我处理缩放它。这就像打印预览一样,效果很好。此外,WPF 图形都是用矢量完成的,因此缩放通常看起来不错。如果放大屏幕截图可能看起来不太好,但缩小屏幕截图可能没问题。

    下面的代码通过实例化我的 UserControl 的新实例(以下代码中的InspectionFormPrintView)来进行打印,设置它的 DataContext(它具有绑定数据),然后从打印驱动程序获取一些信息以正确调整它的大小。它也在 ViewBox 内 - 如果不是,它不会缩放,因为我的控件具有固定大小。

    最后,Dispatcher.BeginInvoke 将实际打印排入队列。由于 WPF 如何布置控件,因此必须这样做(有关详细信息,请参阅我的问题 Why do I need to call Dispatcher.BeginInvoke() to allow a visual to properly bind before printing? 的答案)。

    var dlg = new PrintDialog();
    var result = dlg.ShowDialog();
    if (result == null || !(bool)result)
        return;
    
    var page = new Viewbox { Child = new InspectionFormPrintView { DataContext = this.DataContext } };
    
    page.Measure(new Size(dlg.PrintableAreaWidth, dlg.PrintableAreaHeight));
    page.Arrange(new Rect(new Point(0, 0), page.DesiredSize));
    
    Dispatcher.BeginInvoke(new Action(() => dlg.PrintVisual(page, "UnitHistory Inspection Form")), DispatcherPriority.ApplicationIdle, null);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-31
      • 2018-05-06
      • 1970-01-01
      相关资源
      最近更新 更多