I am experiencing an odd issue with printing from a WPF project. I'm printing a screen capture of the application for reporting purposes, and all that works just fine. Currently the user presses print, the print dialog appears, and they print out the capture image.
However, I want to be able to print directly to the default printer without showing the dialog box. This should be easily done by commenting out the ShowDialog() statement and allowing the rest to just happen. The printer still prints, but the pages are always blank.
Can anyone explain this behavior?
private void PrintCurrentScreen()
{
PrintDialog PD = new PrintDialog();
PD.PrintTicket.OutputColor = OutputColor.Grayscale;
PD.PrintTicket.OutputQuality = OutputQuality.Draft;
PrintTicket PT = new PrintTicket();
PT.PageOrientation = PageOrientation.Landscape;
PT.CopyCount = 1;
PT.PageBorderless = System.Printing.PageBorderless.Borderless;
//---Blank pages print when commented out---//
//if (PD.ShowDialog() == true)
//{
PD.PrintTicket = PT;
DrawingVisual DV = new DrawingVisual();
DV.Offset = new Vector(20, 20);
DrawingContext DC = DV.RenderOpen();
DC.DrawImage(previewimage.Source, new Rect(new Size(PD.PrintableAreaWidth - 40, PD.PrintableAreaHeight - 40)));
DC.Close();
PD.PrintVisual(DV, "TEST");
//}
}
Try doing a Measure, Arrange, and UpdateLayout right before the printvisual, like this:
DV.Measure(new System.Windows.Size(PD.PrintableAreaWidth,
PD.PrintableAreaHeight));
DV.Arrange(new System.Windows.Rect(new System.Windows.Point(0, 0),
DV.DesiredSize));
DV.UpdateLayout();
PD.PrintVisual(DV, "TEST");
Related
I have one user control in which i displayed the map and the data in the datagrid.
I have tried following code but it does not works.
PrintDialog printDialog = new PrintDialog();
// if user clicks on cancel button of print dialog box then no need to print the map control
if (!(bool)printDialog.ShowDialog())
{
return;
}
else // this means that user click on the print button
{
// do nothing
}
this.Measure(new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight));
this.Arrange(new Rect(new Point(20, 20), new Size(this.ActualWidth, this.ActualHeight)));
// print the map control
printDialog.PrintVisual(this, "Karte drucken");
Issue : When data grid has large number of records then user control gets scroll bar, but after printing the user control, only visible part of user control is printed and not the data present which we can see after scrolling down.I want to print whole content of user control.
Is there any solution for this, also how can we see print preview in wpf ?
Please check the following link, it should be helpful. Print Preview WPF
Code
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
if (printDlg.ShowDialog() == true)
{
//get selected printer capabilities
System.Printing.PrintCapabilities capabilities = printDlg.PrintQueue.GetPrintCapabilities(printDlg.PrintTicket);
//get scale of the print wrt to screen of WPF visual
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / this.ActualWidth, capabilities.PageImageableArea.ExtentHeight /
this.ActualHeight);
//Transform the Visual to scale
this.LayoutTransform = new ScaleTransform(scale, scale);
//get the size of the printer page
Size sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
//update the layout of the visual to the printer page size.
this.Measure(sz);
this.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(this, "First Fit to Page WPF Print");
}
I'm trying to print from a WPF application, but struggling to set a default page size.
The content I'm printing is supposed to be on a C5-sized envelope, and most printers here default to A4 paper.
I'd like to show a dialog to the user to allow them to choose the printer to use - but if they just press OK to accept the default printer, it defaults to A4 paper.
How can I set the print defaults for a job to C5 envelop?
Can I still prompt the user for the printer?
private void PrintVisual_Sized(UIElement toPrint)
{
PrintDialog dlg = new PrintDialog();
PrintQueue queue = dlg.PrintQueue;
// Get C5 page size if possible from printer
var availPageSizes = queue.GetPrintCapabilities().PageMediaSizeCapability;
PageMediaSize pageSize = Utilities.GetPageSize(availPageSizes, PageMediaSizeName.ISOC5Envelope);
if (pageSize != null)
{
PrintTicket ticket = new PrintTicket
{
PageMediaSize = pageSize,
InputBin = InputBin.AutoSelect,
CopyCount = 1
};
dlg.UserPageRangeEnabled = false;
var result = dlg.PrintQueue.MergeAndValidatePrintTicket(dlg.PrintTicket, ticket);
Debug.Print(result.ConflictStatus.ToString());
// Try to get the page size honoured by someone!!!
dlg.PrintQueue.DefaultPrintTicket = result.ValidatedPrintTicket;
dlg.PrintQueue.UserPrintTicket = result.ValidatedPrintTicket;
dlg.PrintTicket = result.ValidatedPrintTicket;
// Height still seems to be A4 sized!?
Debug.Print("Height: " + dlg.PrintableAreaHeight);
}
// Ask user which printer they want...
if (dlg.ShowDialog().GetValueOrDefault(false))
{
Size printSize = new Size(dlg.PrintableAreaWidth, dlg.PrintableAreaHeight);
toPrint.Measure(printSize);
toPrint.Arrange(new Rect(new Point(), printSize));
toPrint.UpdateLayout();
dlg.PrintVisual(toPrint, "My Print Job");
}
}
In the last section printSize is A4 unless the user manually selects another paper size.
Is there any way to display the dialog, with a non-default page size preset?
I currently have an application that contains several different grids, each representing a different page that needs to be printed. I was able to build a fixed document and print out everything until I needed to add a chart to one of the grids. Now on two of these Grids it collects user data that is then plotted into a chart using the WPF charting toolkit. When I try to clone the grids that contain the charts and try to add them to the the Fix Document I get a stack overflow execption which is triggered by the line of code
String gridXaml = XamlWriter.Save(GridName);
private void Print_Click(object sender, RoutedEventArgs e)
{
PrintDialog pd = new PrintDialog();
pd.UserPageRangeEnabled = true;
document = new FixedDocument();
AddPage(MPEval);
AddPage(QC);
AddPage(ID);
AddPage(AWS);
AddPage(GAR);
AddPage(SA);
AddPage(UAG);
AddPage(LCD);
AddPage(RFVolume);
AddPage(RFSurface);
if (pd.ShowDialog() == true)
{
DocumentPaginator paginator = document.DocumentPaginator;
if (pd.PageRangeSelection == PageRangeSelection.UserPages)
{
paginator = new PageRangeDocumentPaginator(document.DocumentPaginator, pd.PageRange);
}
pd.PrintDocument(paginator, MPSite.Text);
}
}
private void AddPage(Grid gridName)
{
var pageSize = new Size(8.26 * 96, 11.69 * 96); // A4 page, at 96 dpi
document.DocumentPaginator.PageSize = pageSize;
// Create FixedPage
var fixedPage = new FixedPage();
fixedPage.Width = pageSize.Width;
fixedPage.Height = pageSize.Height;
// Add visual, measure/arrange page.
String gridXaml = XamlWriter.Save(gridName);
StringReader stringReader = new StringReader(gridXaml);
XmlReader xmlReader = XmlTextReader.Create(stringReader, new XmlReaderSettings());
Grid tempGrid = (Grid)XamlReader.Load(xmlReader);
fixedPage.Children.Add((UIElement)tempGrid);
fixedPage.Measure(pageSize);
fixedPage.Arrange(new Rect(new Point(), pageSize));
fixedPage.UpdateLayout();
// Add page to document
var pageContent = new PageContent();
((IAddChild)pageContent).AddChild(fixedPage);
document.Pages.Add(pageContent);
}
Can anyone please point me in the right direction on how to be able to add these to my fixed document or let me know if I have hit a dead end and need to go another route. Any help is greatly appreciated.
Thank you,
Ryan
You can have a look and see if this will work for you:
System.Xaml.XamlServices.Save(GridName);
The problem you are experiencing is due to a recursive call.
I am generating a crystal report using C# and WPF.
My code so far is
report.PrintOptions.PaperSize = (CrystalDecisions.Shared.PaperSize)System.Drawing.Printing.PaperKind.A5;
report.PrintToPrinter(2, true, 0, 0);
crystalReportsViewer1.ViewerCore.ReportSource = report;
crystalReportsViewer1.ToggleSidePanel = SAPBusinessObjects.WPF.Viewer.Constants.SidePanelKind.None;
I need to show a dialog box ie the PrintDialog to allow user just to select the printer he wants to print on and rest of the printing settings are done by me in the code. Please suggest ....
Try the following code
PrintDialog printDialog1 = new PrintDialog();
if (printDialog1.ShowDialog() == true)
{
report.PrintOptions.PrinterName = printDialog1.PrintQueue.Name;
report.PrintOptions.PaperSize = (CrystalDecisions.Shared.PaperSize)System.Drawing.Printing.PaperKind.A5;
report.PrintToPrinter(2, true, 0, 0);
crystalReportsViewer1.ViewerCore.ReportSource = report;
crystalReportsViewer1.ToggleSidePanel = SAPBusinessObjects.WPF.Viewer.Constants.SidePanelKind.None;
}
System.Printing must be in your references so that you can use PrintQueue.Name.
i try to print out the content of my editor:
PrintDialog pd = new PrintDialog();
pd.PageRangeSelection = PageRangeSelection.AllPages;
pd.UserPageRangeEnabled = true;
FlowDocument fd = DocumentPrinter.CreateFlowDocumentForEditor(CurrentDocument.Editor);
DocumentPaginator dp = ((IDocumentPaginatorSource)fd).DocumentPaginator;
bool? res = pd.ShowDialog();
if (res.HasValue && res.Value)
{
fd.PageHeight = pd.PrintableAreaHeight;
fd.PageWidth = pd.PrintableAreaWidth;
fd.PagePadding = new Thickness(50);
fd.ColumnGap = 0;
fd.ColumnWidth = pd.PrintableAreaWidth;
pd.PrintDocument(dp, CurrentDocument.Editor.FileName);
}
The test-document i used has about 14 pages (with this pagesize-settings).
i tested it: the printdialog appears and I´ve chosen a pagerange (i typed "1-3" into the textbox) and clicked print. above the printdocument() I set a breakpoint and looked into the printdialog-object. it says pd.PageRangeSelection = PageRangeSelection.UserPage and pd.PageRange = {1-3}. I guess this is right, because I wanted to print out only page 1-3. then the printdocument() executed and in the output-pdf (for testing I use a pdf-printer) has 14 pages (the whole document was printed).
where is my mistake? why does the pagerange-setting not work?
thanks for your help
In your code you manually set:
pd.PageRangeSelection = PageRangeSelection.AllPages;
This is why your code prints all the pages.
The reason for this is because FlowDocument's DocumentPaginator does not handle UserPageRanges. You can see that FlowDocument implementation creates a FlowDocumentPaginator, and it doesn't take into account ranges.
If it did handle it, in FlowDocumentPaginator.(Async)GetPage you would see, code checking to see if the page requested to be printed is in an index of available pages; or maybe if a key exists in a Dictionary whose value is the DocumentPage to print.
In other words, and the reason the PrintDialog default has UserPageRangeEnabled set to false, is because in order to use that feature, you'll usually have to write your own DocumentPaginator or you have to add some logic to compile a new temporary document to hold only the pages you want to print.
Feel free to ask any questions.