Set Print Orientation on PrintDialog using Flow Document - c#

Just wondering if there is a way to set the print document orientation on a Print Dialog that is using a flow document.
e.g.
var document = userControl.Content as FlowDocument;
var printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
var paginator = ((IDocumentPaginatorSource) document).DocumentPaginator;
paginator.PageSize = new Size(userControl.Width, userControl.Height);
//Set Orientation Landscape .....
printDialog.PrintDocument(paginator, PrintDescription);
}

Use:
printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
You need to add a reference to ReachFramework.dll and System.Printing.dll each.

Related

WPF DocumentViewer Print Landscape Content Cut Off

I'm using DocumentViewer in a WPF XAML project. I create a fixed document with the following code. The page looks fine in the viewer. When I print it, it prints in landscape view, but the top 1-2 cm is cut off! I tried it without the scale transform on the dockpanel but that had no effect.
private void PrintReport()
{
PrintDialog pd = new PrintDialog();
pd.PrintQueue = LocalPrintServer.GetDefaultPrintQueue();
pd.PrintTicket = pd.PrintQueue.DefaultPrintTicket;
pd.PrintTicket.PageOrientation = PageOrientation.Landscape;
pd.PrintDocument(docViewer.Document.DocumentPaginator, "DaySheet");
}
public void BuildReport(DockPanel dpPrint)
{
try
{
// init
ScaleTransform st = new ScaleTransform(0.5, 0.5, 0, 0);
dpPrint.RenderTransform = st;
Size pgSize = new Size(96 * 11.69, 96 * 8.27);
FixedDocument fd = new FixedDocument();
// add page content
FixedPage fp = new FixedPage();
fp.Width = pgSize.Width;
fp.Height = pgSize.Height;
fp.Children.Add(dpPrint);
// set page content
PageContent pc = new PageContent();
pc.Child = fp;
fd.Pages.Add(pc);
// set up fresh XpsDocument
var uri = new Uri("pack://daysheet_report.xps");
PackageStore.RemovePackage(uri);
var stream = new MemoryStream();
var package = Package.Open(stream, FileMode.Create, FileAccess.ReadWrite);
PackageStore.AddPackage(uri, package);
var xpsDoc = new XpsDocument(package, CompressionOption.NotCompressed, uri.AbsoluteUri);
// write FixedDocument to the XpsDocument
var docWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
docWriter.Write(fd);
// display XpsDocument in DocumentViewer
docViewer.Document = xpsDoc.GetFixedDocumentSequence();
docViewer.Document.DocumentPaginator.PageSize = pgSize;
}
catch (Exception ex)
{
gFunc.ProcessError(ex);
}
}
I tried playing around with printer drivers but it seemed to make no difference. The printer driver I have installed is the correct one for my laser printer and the right version for Windows 10 64-bit. When I print from Word, Excel, PDF its all fine, but from my WPF app it crops the top part of the page content.
As is so often the case, I got around the problem with a hack. I just changed the page content to use a StackPanel and I placed a blank TextBlock as the first child to push the other content down.

Add multiple WPF windows as page to one document

I`m trying to print some mark sheets. I created a WPF window and print whole window in this way:
PrintDialog pd = new System.Windows.Controls.PrintDialog();
if (pd.ShowDialog() == true)
{
pd.PrintVisual(this.Content as Visual, "Report");
}
Then I want to add more mark sheet in on document: insert each student marks in that window, add it to a page.
And then print a single file in this way:
PrintDialog pd = new System.Windows.Controls.PrintDialog();
FixedDocument document = new FixedDocument();
document.DocumentPaginator.PageSize = new System.Windows.Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
FixedPage page1 = new FixedPage();
page1.Width = document.DocumentPaginator.PageSize.Width;
page1.Height = document.DocumentPaginator.PageSize.Height;
page1.Children.Add(this);
PageContent page1Content = new PageContent();
((IAddChild)page1Content).AddChild(page1);
document.Pages.Add(page1Content);
FixedPage page2 = new FixedPage();
page2.Width = document.DocumentPaginator.PageSize.Width;
page2.Height = document.DocumentPaginator.PageSize.Height;
page2.Children.Add(this);
PageContent page2Content = new PageContent();
((IAddChild)page2Content).AddChild(page2);
document.Pages.Add(page2Content);
if (pd.ShowDialog() == true)
{
pd.PrintDocument(document.DocumentPaginator, "My first document");
}
But the problem is when I add Window (this) to pages as element:
page1.Children.Add(this);
I have Window must be the root of the tree.Cannot add Window as a child of Visual. Source=< Cannot evaluate the exception source> error.

How to print flowdocument in landscape (WPF,C#)?

I'd like to print my programmatically created flowdocument in landscape mode and I tried all versions what I've found but none of them works.
Here's my code below:
try
{
// Create a PrintDialog
PrintDialog printDlg = new PrintDialog();
printDlg.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
// Create a FlowDocument dynamically.
FlowDocument doc = CreateFlowDocumentSum();
doc.Name = "FlowDoc";
doc.ColumnWidth = printDlg.PrintableAreaWidth;
// Create IDocumentPaginatorSource from FlowDocument
IDocumentPaginatorSource idpSource = doc;
// Call PrintDocument method to send document to printer
printDlg.PrintDocument(idpSource.DocumentPaginator, "sum");
doc.Blocks.Clear();
sumTable.Clear();
}
catch
{ }
I did it finally.
Just modified the code in the print button event:
PrintDialog printDlg = new PrintDialog();
LocalPrintServer ps = new LocalPrintServer();
PrintQueue pq = ps.DefaultPrintQueue;
PrintTicket pt = pq.UserPrintTicket;
pt.PageOrientation = PageOrientation.Landscape;
FlowDocument doc = CreateFlowDocumentSum();
doc.PageHeight = 768;
doc.PageWidth = 1104;
PageMediaSize pageMediaSize = new PageMediaSize(doc.PageWidth, doc.PageHeight);
pt.PageMediaSize = pageMediaSize;
IDocumentPaginatorSource source = doc as IDocumentPaginatorSource;
printDlg.PrintDocument(source.DocumentPaginator, "sum");
Then in my FlowDocument I set the width and height:
FlowDocument docSum = new FlowDocument();
docSum.PageHeight = 768;
docSum.PageWidth = 1104;
docSum.ColumnWidth = 1104;

Forcing a FlowDocument to Load?

I'm in the process of trying to print out a FlowDocument that is being viewed by the user. I wrote a routine to create a copy of the original document so that changes (from the PrintDialog) don't get reflected into the DocumentViewer.
Unfortunately, my copy seems to have lost all of the information bound to its fields. I've tried resetting the DataContext but the copy's IsLoaded property is still coming back false, leading me to believe that the binding isn't occuring.
Any ideas?
Here's the code I'm using to copy the document:
private static void AddDocument(FlowDocument from, FlowDocument to)
{
TextRange tr = new TextRange(from.ContentStart, from.ContentEnd);
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
TextRange tr2 = null;
System.Windows.Markup.XamlWriter.Save(tr, ms);
tr.Save(ms, DataFormats.XamlPackage, true);
tr2 = new TextRange(to.ContentEnd, to.ContentEnd);
tr2.Load(ms, DataFormats.XamlPackage);
}
}
And here's the code I'm using to print the document:
public static void PrintFlowDocument(FlowDocument fd, string title)
{
PrintDialog pd = new PrintDialog();
IDocumentPaginatorSource idps = null;
FlowDocument flowDoc = new FlowDocument();
AddDocument(fd, flowDoc);
flowDoc.DataContext = fd.DataContext;
flowDoc.PageHeight = pd.PrintableAreaHeight;
flowDoc.PageWidth = pd.PrintableAreaWidth;
flowDoc.PagePadding = new Thickness(50);
flowDoc.ColumnGap = 0;
flowDoc.ColumnWidth = pd.PrintableAreaWidth;
idps = flowDoc;
if (pd.ShowDialog() == true)
{
pd.PrintDocument(idps.DocumentPaginator, title);
}
}
Thanks in advance,
Sonny
Notice some off about this line?
tr2 = new TextRange(to.ContentEnd, to.ContentEnd);
I had similar issues and found the forcing the document creation to a background thread gave the binding an opportunity to fire. Otherwise, it would not happen on the UI thread.
So, if your copy document method were a function it would be something like this:
Dim flowDoc As FlowDocument =
DirectCast(<ViewInstance>.UIDispatcher.Invoke(Function()
AddFlowDocument(fd),
Windows.Threading.DispatcherPriority.Background),
FlowDocument)

WPF to XPS in landscape orientation

i am trying to to generate a XPS Document from a WPF Control. Printing works so far, but i cannot find a way to create the XPS in landscape mode.
My code to create the XPS file, mostly taken from another SO page
public FixedDocument ReturnFixedDoc()
{
FixedDocument fixedDoc = new FixedDocument();
PageContent pageContent = new PageContent();
FixedPage fixedPage = new FixedPage();
var ctrl = new controlToPrint();
//Create first page of document
fixedPage.Children.Add(ctrl);
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
fixedDoc.Pages.Add(pageContent);
//Create any other required pages here
return fixedDoc;
}
public void SaveCurrentDocument()
{
// Configure save file dialog box
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "MyReport"; // Default file name
dlg.DefaultExt = ".xps"; // Default file extension
dlg.Filter = "XPS Documents (.xps)|*.xps"; // Filter files by extension
// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process save file dialog box results
if (result == true)
{
// Save document
string filename = dlg.FileName;
FixedDocument doc = ReturnFixedDoc();
XpsDocument xpsd = new XpsDocument(filename, FileAccess.Write);
System.Windows.Xps.XpsDocumentWriter xw = XpsDocument.CreateXpsDocumentWriter(xpsd);
xw.Write(doc);
xpsd.Close();
}
}
Any help is appreciated.
Try setting the size of your FixedPage in ReturnFixedDoc:
// hard coded for A4
fixedPage.Width = 11.69 * 96;
fixedPage.Height = 8.27 * 96;
The numbers are in the form (inches) x (dots per inch). 96 is the DPI of WPF. I have used the dimensions of an A4 page.

Categories