1

I have to print to specified printer (price-label printer) some data. Data looks like ean13 barcode, price, item's title, etc

I have a few settings what to print in each case. What I want:

  • create usercontrol (WPF) with 2 columns. left column for print preview, and right column for settings (checkboxes, textboxes).
  • is user changes settings, print preview updates.

What approach should I use, to do it most right way? Now printing routine looks like:

private void DrawOnGraphics(Graphics graphics)
{
    using (var shF = new Font("Arial", 10, FontStyle.Bold))
    {
        graphics.DrawImage(_barcode, new Point(0, 0));
// etc...
}

I think it's not very good code but it works here:

var pDoc = new PrintDocument();
pDoc.PrintPage += (a, e) =>
                              {
                                  DrawOnGraphics(e.Graphics);
                                  e.HasMorePages = false;
                              };
pDoc.Print();

Can I create one 'rendering routine' for both actions: print and printpreview? Thanks. How can it be done? Should I use in XAML for print preview

<Image Source="{Binding Path=PrintPreviewImage}" />

or? :)

Main question is: how to draw own things (text, images, etc) for print and printpreview in WPF.

Lari13
  • 1,850
  • 10
  • 28
  • 55

1 Answers1

0

I tried this approach:

  • in ViewModel, I have public property PrintPreview (of type Grid)

  • in XAML i have

    <ContentPresenter Content="{Binding Path=PrintPreview}" />
    
  • each of settings are binded to ViewModel properties

  • in private function I contruct PrintPreview property like this:

    PrintPreview.Children.Clear(); var title = new TextBlock { ... }; PrintPreview.Children.Add(title); //etc.

  • I have "Print" method, that is binded to button "Print" in view:

    PrintQueue pq = new PrintServer().GetPrintQueues(new[]
                                                         {
                                                             EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections
                                                         }).FirstOrDefault(tmp => tmp.FullName.Contains("MyPrintername"));
    
    if (pq == null)
    {
        MessageBox.Show("Please, setup printer");
        return;
    }
    
    var pt = new PrintTicket();
    // setting printticket
    pt.PageMediaSize = new PageMediaSize(FromMMtoPx(96, WidthInMm), FromMMtoPx(96, HeightInMm));
    pt.CopyCount = Copies;
    pt.PageResolution = new PageResolution(203, 203);
    pt.PageOrientation = PageOrientation.Portrait;
    pt.PageBorderless = PageBorderless.Borderless;
    
    var pDoc = new System.Windows.Controls.PrintDialog();
    pDoc.PrintQueue = pq;
    pDoc.PrintTicket = pt;
    
    // scale for whole printer page:
    
    var capabilities = pDoc.PrintQueue.GetPrintCapabilities(pDoc.PrintTicket);
    double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / PrintPreview.ActualWidth, capabilities.PageImageableArea.ExtentHeight / PrintPreview.ActualHeight);
    
    PrintPreview.LayoutTransform = new ScaleTransform(scale, scale);
    var sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
    PrintPreview.Measure(sz);
    PrintPreview.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
    pDoc.PrintVisual(PrintPreview, "MyPrint");
    

It works, but I don't really know, is that good approach or not.

Julien Poulin
  • 12,737
  • 10
  • 51
  • 76
Lari13
  • 1,850
  • 10
  • 28
  • 55