I'm using the PrintPreviewDialog. Works great, but I really need to allow the user to select a printer instead of just having the print go directly to the default printer.
Try to use the PrintDialog class, for example in the next manner:
<Button Width="200" Click="InvokePrint">Invoke PrintDialog</Button>
private void InvokePrint(object sender, RoutedEventArgs e)
{
// Create the print dialog object and set options
PrintDialog pDialog = new PrintDialog();
pDialog.PageRangeSelection = PageRangeSelection.AllPages;
pDialog.UserPageRangeEnabled = true;
// Display the dialog. This returns true if the user presses the Print button.
Nullable<Boolean> print = pDialog.ShowDialog();
if (print == true)
{
XpsDocument xpsDocument = new XpsDocument("C:\\FixedDocumentSequence.xps", FileAccess.ReadWrite);
FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();
pDialog.PrintDocument(fixedDocSeq.DocumentPaginator, "Test print job");
}
}
Related
I am currently developing a WPF application using C# language and .Net Framework 4.8
In the MainWindow I have the Print menu button to generate a Fixed Document like this
private void clPrintMenu_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
/* Margins is a User-defined structure to set Top, Right, Bottom and Left values
in Cm, Inches and Pixels */
Margins margins = new Margins(21, 29.7);
margins.Unit = Units.Pixel;
Size sz = new Size(margins.Left.Value, margins.Top.Value);
FixedDocument document = new FixedDocument();
document.DocumentPaginator.PageSize = sz;
/* CashJournal is a UserControl designed as an A4 sheet the list below contains several
Cashjournal which represent multiple pages */
List<CashJournal> journals = CashJournal.PrintJournals;
foreach (CashJournal jrl in journals)
{
FixedPage page = new FixedPage();
page.Width = margins.Left.Value;
page.Height = margins.Top.Value;
FixedPage.SetLeft(jrl, 0);
FixedPage.SetTop(jrl, -20);
page.Children.Add(jrl);
PageContent content = new PageContent();
((IAddChild)content).AddChild(page);
document.Pages.Add(content);
}
/* The document is then passed to a window for preview */
CashPrintPreview dialog = new CashPrintPreview(selectedTab, document);
dialog.ShowDialog();
}
In the CashPrintPreview, the document is displayed in a DocumentViewer which has a Print button. I modifed the Print() CommandBinding to bind the function to my custom function PrintPreview
private void PrintView(object sender, ExecutedRoutedEventArgs e)
{
PrintDialog dialog = new PrintDialog();
bool? rslt = dialog.ShowDialog();
if (rslt != true)
return;
/* This block is my problem */
PrintQueue queue = dialog.PrintQueue;
PrintCapabilities capabilities = queue.GetPrintCapabilities();
Size sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
document.DocumentPaginator.PageSize = sz;
XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(queue);
writer.Write(document);
}
When I choose the XPS printer from the PrintDialog, the created file render perfectly as it appears in the preview. But when I choose the PDF printer from Adobe the document is not well scaled like too much margins on top and not enough margins on left.
How can I resolve this issue. Thanks.
PS. Please be explicit.
I am finally able to print a FixedDocument to PDF using the Acrobat printer. I just needed to pass my document to the PrintDocument function of the chosen printer:
private void PrintView(object sender, ExecutedRoutedEventArgs e)
{
PrintDialog dialog = new PrintDialog();
bool? rslt = dialog.ShowDialog();
if (rslt != true)
return;
dialog.PrintDocument(((IDocumentPaginatorSource)document).DocumentPaginator, "");
}
Using
using System.Drawing.Printing;
using System.Windows.Forms;
private void Main()
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
PrintDialog pdi = new PrintDialog();
pdi.Document = pd;
// -> preventing PrintDialog from changing the default printer
// -> BUT changing the PrintDocuments-Printer to the selected??
if (pdi.ShowDialog() == DialogResult.OK)
{
pd.Print();
// -> OR reset default Printer?
}
}
private void pd_PrintPage(object sender, PrintPageEventArgs ev)
{
//- do the printing
ev.HasMorePages = false;
}
always changes the default Windows Printer if the user selects a printer with PrintDialog:
How can I prevent the change by PrintDialog? And how to set the selected Printer for PrintDocument
or
Do I need to reset the default printer after printing? How?
or
Am I'm doing something wrong (I need to develop with Net Framework 2.0)
Regards Thomas
I need to send all the images in a folder to printer at once. This is possible from windows explorer where we select all the image files, right click and select print to send all the selected images to print dialog from where we can select printer settings and proceed to print. How do I do this from within c# windows form Application?
Edit: I came up with this but it prints only the last page. How should I modify this?
private void printAllCardSheetBtn_Click(object sender, EventArgs e)
{
PrintDocument pdoc = new PrintDocument();
pdoc.DocumentName = "cardsheets";
PrintDialog pd = new PrintDialog();
if(pd.ShowDialog() == DialogResult.OK)
{
PrinterSettings ps = pd.PrinterSettings;
pdoc.PrinterSettings = ps;
pdoc.PrintPage += pdoc_PrintPage;
pdoc.Print();
}
}
void pdoc_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
string[] sheetpaths = Directory.GetFiles(_sheetDirectory);
Point point = new Point(0, 0);
foreach (string s in sheetpaths)
{
g.DrawImage(new Bitmap(s), point);
}
}
You can use PrintDocument.
Just get all images from folder, load them to a Bitmap and through a For Loop use PrintDocument to print one by one.
BTW, use PrintPage event and with PrintPageEventArgs you can draw the image in the document to print with Graphics.
Cheers
EDIT: Check this example -> Example
I have a bitmap I want the user to see before he prints it. So I open for him print preview, if the user decides to print I want to execute some code.
The problem is, printPreviewDialog will not return an answer. This may be because it has only a print button and close button, but no print-and-close so I can know the user decided to print.
If you have a solution for that I'll be happy, if you think it's not the best way to do so please tell me.
code:
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(Print_Page);
PrintPreviewDialog pritdlg = new PrintPreviewDialog();
pritdlg.Document = pd;
if (pritdlg.ShowDialog() == DialogResult.OK)
pd.Print();
else
MessageBox.Show("you have canceled print");
private void Print_Page(object o, PrintPageEventArgs e)
{
e.Graphics.DrawImage(target, 0,0);
}
Subscribe to the EndPrint event of the document you are sending to the printPreviewDialog control, then check the PrintAction in its PrintEventArgs argument.
Example:
private void buttonPrintPreview_Click(object sender, EventArgs e)
{
PrintPreviewDialog printDialog = new PrintPreviewDialog();
printDialog.Document = yourDocument;
yourDocument.EndPrint += doc_EndPrint; // Subscribe to EndPrint event of your document here.
printDialog.ShowDialog();
}
void doc_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
if (e.PrintAction == System.Drawing.Printing.PrintAction.PrintToPrinter)
{
// Printing to the printer!
}
else if (e.PrintAction == System.Drawing.Printing.PrintAction.PrintToPreview)
{
// Printing to the preview dialog!
}
}
i already can create a print to print a file in my windows forms. However, whenever i add this code:
printDialog.PrinterSettings.DefaultPageSettings.Landscape = true;
I can't see the Orientation of the page become LandScape, it is still Portrait.
How do I make it LandScape as default? So, whenever i click PrintPreview or PrintFile, the Orientation of the page will become LandScape, not Portrait.
Here is the code:
private void PrintPreview(object sender, EventArgs e)
{
PrintPreviewDialog _PrintPreview = new PrintPreviewDialog();
_PrintPreview.Document = printDocument1;
((Form)_PrintPreview).WindowState = FormWindowState.Maximized;
_PrintPreview.ShowDialog();
}
private void PrintFile(object sender, EventArgs e)
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument1;
printDialog.UseEXDialog = true;
if (DialogResult.OK == printDialog.ShowDialog())
{
printDocument1.DocumentName = "Test Page Print";
printDocument1.Print();
}
}
try setting the Landscape of PrintDocument as follows,
printDocument1.DefaultPageSettings.Landscape = true;
The pdfprinting.net library is excellent for implementing the print functionality and be productive. Here is the simple code snippet to set print orientation to landscape(pdfPrint.IsLandscape = true;)
var pdfPrint = new PdfPrint("demoCompany", "demoKey");
string pdfFile = #"c:\test\test.pdf";
pdfPrint.IsLandscape = true;
int numberOfPages = pdfPrint.GetNumberOfPages(pdfFile);
var status = pdfPrint.Print(pdfFile);
if (status == PdfPrint.Status.OK) {
// check the result status of the Print method
// your code here
}
// if you have pdf document in byte array that is also supported
byte[] pdfContent = YourCustomMethodWhichReturnsPdfDocumentAsByteArray();
status = pdfPrint.Print(pdfFile);