Real size WPF controls for printing

混江龙づ霸主 提交于 2019-12-12 17:15:36

问题


I am currently developing an application where users can create/move TextBlocks on a canvas dynamically. Once they have positioned the TextBlocks where they want them they can press a print button which will cause a ZPL printer to print what is currently displayed on screen.

The ZPL commands are built by taking the following values from each TextBlock:

  • XPosition = Canvas.Left
  • YPosition = Canvas.Right
  • Text = Text

However I can't find a way of getting the printout to resemble the on screen display. I guess this is because the values of Canvas.Left and Canvas.Right do not match up with the printers DPI.

Here is the conversion I am currently using (because I thought the Canvas.Left = 1 means 1/96th of an inch) (Top left of the canvas is 0,0)

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

Is there I can display controls in "real size". The paper being used will always be A5 (8.3 in x 5.8 in).

I thought about using a viewbox around a Canvas which had its width and height set to 830 x 580 (ratio correct for A5) however this didn't help.

Any suggestions??

Thanks


回答1:


Instead of what you're doing, take a "screenshot" of the entire canvas and print that.

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



回答2:


I just got done writing a form designer of sorts. Here's what I did:

I have a UserControl, that is 850x1100 units in size (WPF units, but think "letter sized paper :)"), and the size is fixed. I place my controls on that where ever I want, I display this control in a Window inside a ViewBox, which handles scaling it for me. This works like a print preview, and works very well. Also, WPF graphics are all done with vectors, making scaling usually look pretty good. Screenshots might not look as good if scaled up, but scaled down might be ok.

The code below does the printing by instantiating a new instance of my UserControl (InspectionFormPrintView in the following code), setting its DataContext (it has bound data), then get some information from the print driver to size it properly. It's also inside a ViewBox - if not, it won't scale since my control has a fixed size.

Finally, the Dispatcher.BeginInvoke queues up the actual print. This has to be done due to how WPF lays out controls (see the answer to my question Why do I need to call Dispatcher.BeginInvoke() to allow a visual to properly bind before printing? for more information).

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


来源:https://stackoverflow.com/questions/18218061/real-size-wpf-controls-for-printing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!