9

I'm trying to add printing support to a C# WPF application I'm writing and I'm tearing my hair out over this. I'm trying to print a single image from a window in a WPF application. The image is a shipping label and the printer is a thermal printer loaded with 4"x6" shipping label stock. The code to print is as follows:

PrintDialog pd = new PrintDialog();

if (pd.ShowDialog() == true)
{
    Image tmpImage = new Image();
    tmpImage.Stretch = Stretch.Uniform;
    tmpImage.Width = pd.PrintableAreaWidth;
    tmpImage.Source = this.img_label.Source;
    tmpImage.Measure(new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight));
    tmpImage.Arrange(new Rect(new Point(0, 0), tmpImage.DesiredSize));

    pd.PrintVisual(tmpImage, "Shipping Label");
}

This code works in that it will display the print dialog, I can choose my printer, configure it to use the correct label stock, and print the label. However, as other posts have indicated, it does not save the settings I have selected. So, if I choose to print the same image again without closing the application in between, it reverts to the default printer and, even when I choose the correct printer, defaults that printer to the default settings, which includes using the wrong size label stock. So every time I print I have to select the printer and configure it to use the correct stock. This is simply not acceptable in real world use.

After much searching online I have found numerous posts about this but all of them talk about saving the PrintDialog.PrinterSettings object and then using that to initialize the next PrintDialog instance. However, in WPF, there is no PrinterSettings member of the PrintDialog class. That is a Win Forms object. Why the Win Forms and WPF PrintDialog objects are different is beyond me, but that's likely a question that won't get answered. The real question is what I do now. I can, if necessary, re-invent the entire wheel and have my own printer selector and printer configuration pages and print the image using a PrintDocument object and bypass the PrintDialog entirely. I'd rather not do this unless it is entirely necessary. Displaying the PrintDialog is nice, it's what people are used to, and it already has all the ability to configure the printer built right in. But how can I initialize the PrintDialog in WPF to select the proper printer and use the proper printer settings? If only I were using Windows Forms this would be built in. What's the WPF equivalent?

The secondary question is, if there is no WPF equivalent, what is the recommended way to handle this? I don't really need to give the user the ability to configure the printer within my application. All I want it to do is remember the previous settings they chose the next time they go to print, just like every single other PC application that has ever been written. How can this be so hard?

Any help anyone can provide would be greatly appreciated. In the mean time I'm going down the path of re-inventing the proverbial wheel. I hope to get an easier answer soon.

Thanks!

2 Answers 2

12

WPF has PrintTicket and PrintQueue classes (and PrintDialog has corresponding properties, which can be initialized with your saved settings).

For the simplicity, you can consider the first one as the paper settings, and the second one - as the printer settings (selected printer).

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you Dennis! I had looked at those classes but they were complicated and confusing and I didn't think they would help me. I tested this by saving the PrintTicket and PrintQueue objects to variables and initializing my PrintDialog with the saved values the next time and it works! I just need a way to save these for future use if the user closes and re-opens the application. Is there a way to make the settings the new defaults or can I serialize the objects and save as settings of the application?
@BrianVPS: I fact, you need a printer name and paper size. Why just don't serialize them? I'm not sure, that PrintQueue is serializable...
I suppose I could just save those, but I was concerned that they may change the print quality or tweak other settings that I wouldn't expect and I'd want to make sure I save everything. But if that isn't simple, I can just save those 2 and modify the program to save additional settings if that becomes a problem. Thanks so much for your help!
0

Thanks to Dennis' answer I started looking in that direction

found this question: How to determine the default printer using WPF? and just used that and queried the collection to point at a printer and set it as the printer in question using it's name:

var printerCollection = new LocalPrintServer().GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
pd.PrintQueue = printerCollection.Where(n => n.FullName == "MyPrinterName").FirstOrDefault();

this solves the "...it reverts to the default printer..." portion of the original question.

Originally used this to get all the Installed Printers: https://www.c-sharpcorner.com/UploadFile/iersoy/get-all-installed-printers-in-C-Sharp/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.