0
votes

I have a C# WPF application that is supposed to print labels from a Zebra printer. The Zebra printer is setup as a generic text printer (as opposed to using a Zebra/other driver). The label's ZPL code is already generated and when I print the ZPL code from a text editor such as Notepad or Notepad++, the label prints perfectly fine. When I print the same string from my WPF application, I get different results.

What could be causing theses different results? I've verified and re-copied the ZPL code into my application several times, so I'm quite confident the ZPL is the same. Is there a better method of printing via C# WPF applications? The idea is to allow the user to setup the Zebra printer as a standard Windows printer and select it at print time from the PrintDialog.

Here is my code for printing:

        System.Windows.Controls.PrintDialog prnt = new PrintDialog();            
        prnt.PageRangeSelection = PageRangeSelection.AllPages;
        prnt.UserPageRangeEnabled = false;                        

        Nullable<bool> result = prnt.ShowDialog();

        if (result == true)
        {

            string zpl = "^XA" + Environment.NewLine +
                "^RS,,,3,N,,,2" + Environment.NewLine +
                "^RR3" + Environment.NewLine +
                "^XZ" + Environment.NewLine +
                "^XA" + Environment.NewLine +
                "^SZ2^JMA" + Environment.NewLine +
                "^MCY^PMN" + Environment.NewLine +
                "^PW459" + Environment.NewLine +
                "^LT41" + Environment.NewLine +
                "~JSN" + Environment.NewLine +
                "^MD30" + Environment.NewLine +
                "^JZY" + Environment.NewLine +
                "^LH0,0^LRN" + Environment.NewLine +
                "^XZ" + Environment.NewLine +
                "^XA" + Environment.NewLine +
                "^FT31,42" + Environment.NewLine +
                "^CI0" + Environment.NewLine +
                "^A0N,23,31^FDAsset ID:^FS" + Environment.NewLine +
                "^FT31,74" + Environment.NewLine +
                "^A0N,23,31^FDA0000001^FS" + Environment.NewLine +
                "^FT31,106" + Environment.NewLine +
                "^A0N,23,31^FDItem Code:^FS" + Environment.NewLine +
                "^FT31,137" + Environment.NewLine +
                "^A0N,23,31^FD500124^FS" + Environment.NewLine +
                "^FT49,324" + Environment.NewLine +
                "^A0N,23,31^FDShuttleworth conveyor^FS" + Environment.NewLine +
                "^FT49,346" + Environment.NewLine +
                "^A0N,23,31^FDnylon rollers - A^FS" + Environment.NewLine +
                "^FT49,369" + Environment.NewLine +
                "^A0N,23,31^FDsection of roller is 4-1/2^FS" + Environment.NewLine +
                "^FT49,392" + Environment.NewLine +
                "^A0N,23,31^FDlong with a deep pocket...^FS" + Environment.NewLine +
                "^FT31,172" + Environment.NewLine +
                "^A0N,23,31^FDMfgr Part:^FS" + Environment.NewLine +
                "^FT31,202" + Environment.NewLine +
                "^A0N,23,31^FD701646-231A^FS" + Environment.NewLine +
                "^FT31,254" + Environment.NewLine +
                "^A0N,23,31^FDStore:^FS" + Environment.NewLine +
                "^FT258,254" + Environment.NewLine +
                "^A0N,23,31^FDBin:^FS" + Environment.NewLine +
                "^FT31,289" + Environment.NewLine +
                "^A0N,23,31^FDB5 Maint^FS" + Environment.NewLine +
                "^FT258,289" + Environment.NewLine +
                "^A0N,23,31^FDE6B^FS" + Environment.NewLine +
                "^FO258,23" + Environment.NewLine +
                "^BY1^BCN,38,N,N^FD>:A0>5000001^FS" + Environment.NewLine +
                "^FO258,87" + Environment.NewLine +
                "^BCN,38,N,N^FD>;500124^FS" + Environment.NewLine +
                "^RFW,H,1,2,1^FD1400^FS" + Environment.NewLine +
                "^RFW,H,2,4,1^FDA0000001^FS" + Environment.NewLine +
                "^PQ1,0,1,Y" + Environment.NewLine +
                "^XZ" + Environment.NewLine;

            var doc = new FlowDocument();
            doc.ColumnWidth = prnt.PrintableAreaWidth;

            Paragraph p = new Paragraph();
            p.Inlines.Add(zpl);
            doc.Blocks.Add(p);
            prnt.PrintDocument(((IDocumentPaginatorSource)doc).DocumentPaginator, "Label A0000001");

            //doc.Blocks.Add(new Paragraph(new Run(zpl)));
            //prnt.PrintDocument(((IDocumentPaginatorSource)doc).DocumentPaginator, "Label A0000001");
            //prnt.PrintDocument((Section)XamlReader.Parse(zpl));                 
            
        }

Here are the results of printing labels from the text editor (left) vs my application (right): text editor left, app right

1
I would use a stgtream reader and make sure fonts are same as text editor. See : docs.microsoft.com/en-us/dotnet/api/…jdweng
@jdweng I actually tried that method. The problems I encountered were a: it prints to the default printer; and b: it prints the ZPL code verbatim with whatever the selected font is. Using the PrintDialog in WPF. I couldn't find a way to get the printer name from WPF's System.Windows.Controls.PrintDialog.Smitty-Werben-Jager-Manjenson
I don't know why you need the doc and paragraph. You should be able to print without according to the link. I would try merging you existing code and the link without using any unecessary methods.jdweng
You shouldn't use that flowdocument at all. Not for printing. Zpl needs to be passed raw to the zebra printer, this is low level commands you're sending. Eg You can take zpl and send it to an ip address a zebra printer is on. There's an sdk and samples and support forum. supportcommunity.zebra.com/s/article/…Andy
@Andy you're right, I am trying to send raw ZPL to the printer. The problem I am having is how do I send raw data to the printer. I guess what I'll have to do is create a temporary text file and print the file. I was looking for a way to send the ZPL command directly to the printer selected from the PrintDialog, without creating a file.Smitty-Werben-Jager-Manjenson

1 Answers

0
votes

I was able to solve my issue by using the following code:

System.Windows.Controls.PrintDialog prnt = new PrintDialog();            
prnt.PageRangeSelection = PageRangeSelection.AllPages;
prnt.UserPageRangeEnabled = false;

Nullable<bool> result = prnt.ShowDialog();

if (result == true)
{
    ZPL = "<My ZPL>"; // Global string variable
    PrintDocument pdoc = new PrintDocument();
    pdoc.PrintPage += pdoc_PrintPage;
    pdoc.PrinterSettings.PrinterName = prnt.PrintQueue.FullName; 
    pdoc.Print();
}

Then in the PrintPage event:

void pdoc_PrintPage(object sender, PrintPageEventArgs ev)
{
    // printFont is a global Font variable set to new Font("Arial", 10)
    ev.Graphics.DrawString(ZPL, printFont, System.Drawing.Brushes.Black, 0, 0, new StringFormat());           
}

Now, automatically selecting the last used printer in the PrintDialog is my next challenge.