How to print flowdocument in landscape (WPF,C#)? - 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;

Related

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.

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)

Set Print Orientation on PrintDialog using Flow Document

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.

Add Checkbox to Paragraph

Hy!
I want to add a checkbox to a paragraph.
My code:
PrintDialog pd = new PrintDialog();
pd.ShowDialog();
FlowDocument doc = new FlowDocument();
Paragraph ph = new Paragraph();
ph.Inlines.Add(new Bold(new Run("TODO\n")));
foreach (CheckBox cb in box.Items)
{
int value = Convert.ToInt32("0x6F", 16);
string stringValue = Char.ConvertFromUtf32(value);
CheckBox bt = new CheckBox();
bt.IsChecked = false;
ph.Inlines.Add(new Run(bt + " "+cb.Content.ToString()));
}
doc.Name = "FlowDoc";
doc.Blocks.Add(ph);
IDocumentPaginatorSource idpSource = doc;
pd.PrintDocument(idpSource.DocumentPaginator, "Hello WPF Printing.");
the output is wrong:
TODO System.Windows.Controls.CheckBox Content: IsChecked:False hahaSystem.Windows.Controls.CheckBox Content: IsChecked:False haha1System.Windows.Controls.CheckBox Content: IsChecked:False hallo
Please help!
You could use BlockUIContainer http://msdn.microsoft.com/en-us/library/system.windows.documents.blockuicontainer.aspx
PrintDialog pd = new PrintDialog();
pd.ShowDialog();
FlowDocument doc = new FlowDocument();
Paragraph ph = new Paragraph();
StackPanel sp = new StackPanel();
BlockUIContainer buc = new BlockUIContainer(sp);
ph.Inlines.Add(new Bold(new Run("TODO\n")));
foreach (CheckBox cb in box.Items)
{
int value = Convert.ToInt32("0x6F", 16);
string stringValue = Char.ConvertFromUtf32(value);
CheckBox bt = new CheckBox();
bt.IsChecked = false;
bt.Content = cb.Content;
//ph.Inlines.Add(new Run(bt + " " + cb.Content.ToString()));
sp.Children.Add(bt);
}
doc.Name = "FlowDoc";
doc.Blocks.Add(ph);
doc.Blocks.Add(buc);
IDocumentPaginatorSource idpSource = doc;
pd.PrintDocument(idpSource.DocumentPaginator, "Hello WPF Printing.");

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