WPF - Print content on same page - wpf

I have a requirement to print the WPF form contents on a Save button click. The content is plain text and will be name value pairs on each line. I don't need page breaks on consecutive Saves.
I have tried out the samples for PrintDialog, FlowDocument and FixedDocument and could not avoid the page break.
Is there any particular setting I am missing ?
Any alternative to PrintDialog ?
Code:
Paragraph myParagraph = new Paragraph();
myParagraph.Margin = new Thickness(0);
**myParagraph.BreakPageBefore = false;**
foreach (string line in textToPrint.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
{
myParagraph.Inlines.Add(new Run(line));
}
flowDocument.Blocks.Add(myParagraph);
DocumentPaginator paginator = ((IDocumentPaginatorSource)flowDocument).DocumentPaginator;
printDialog.PrintDocument(paginator, "Test Page");

A new Print job (Document) starts with a new page as far as I know. If you don't want page breaks gather all the values you want to print and then print them.

Related

WPF printing - PrintableAreaWidth & Height stuck in landscape?

I'm printing a FlowDocument using the following code:-
var printDialog = new PrintDialog();
var result = printDialog.ShowDialog();
if (!result.Value)
{
return;
}
var pageWidth = printDialog.PrintableAreaWidth;
var pageHeight = printDialog.PrintableAreaHeight;
flowDoc.ColumnWidth = pageWidth;
flowDoc.PageWidth = pageWidth;
flowDoc.PageHeight = pageHeight;
var paginator = ((IDocumentPaginatorSource)flowDoc).DocumentPaginator;
printDialog.PrintDocument(paginator, "Name");
The print dialog shows the page as being A4 Portrait, however the values of printDialog.PrintableAreaWidth and .PrintableAreaHeight are 1122 & 793 respectively, i.e. landscape.
Changing the orientation or the paper size via the dialog has no effect on these values. What's going on?
Update
I've added a screenshot showing the PrintDialog properties. Notice how the PrintTicket property reflects the correct page size and orientation, yet the two PrintableArea... properties are the wrong way around.
I'm starting to think this is a "funny" with the printer/driver. I've tried printing to the "XPS Document Writer" printer, and the pages render correctly when I view the created file. (And if I view the PrintDialog's properties, the PrintableArea... properties correctly reflect an A4 portrait page).

Printing text in Silverlight that measures larger than page

I have a silverlight application that allows people to enter into a notes field which can be printed, the code used to do this is:
PrintDocument pd = new PrintDocument();
Viewbox box = new Viewbox();
TextBlock txt = new TextBlock();
txt.TextWrapping = TextWrapping.Wrap;
Paragraph pg = new Paragraph();
Run run = new Run();
pg = (Paragraph)rtText.Blocks[0];
run = (Run)pg.Inlines[0];
txt.Text = run.Text;
pd.PrintPage += (s, pe) =>
{
double grdHeight = pe.PrintableArea.Height - (pe.PageMargins.Top + pe.PageMargins.Bottom);
double grdWidth = pe.PrintableArea.Width - (pe.PageMargins.Left + pe.PageMargins.Right);
txt.Width = grdWidth;
txt.Height = grdHeight;
pe.PageVisual = txt;
};
pd.Print(lblTitle.Text);
This simply prints the content of the textbox on the page however some of the notes are spanning larger than the page itself causing it to be cut off. How can I change my code to measure the text and add more pages OR is there a better way to do the above where it will automatically create multiple pages for me?
There are several solutions to your problem, all of them under "Multiple Page Printing Silverlight" on Google. I was having a similar problem and tried most of them. The only one that worked for me was this one:
http://www.codeproject.com/Tips/248553/Silverlight-converting-to-image-and-printing-an-UI
But honestly you should look at Google first and see whether there are better solutions to your specific problem.
Answering your question, there is a flag called HasMorePages that indicates you need a new page. Just type pe.HasMorePages and you will see.
Hope it helps
First you need to work out how many pages are needed
Dim pagesNeeded As Integer = Math.Ceiling(gridHeight / pageHeight) 'gets number of pages needed
Then once the first page has been sent to the printer, you need to move that data out of view and bring the new data into view ready to print. I do this by converting the whole dataset into an image/UI element, i can then adjust Y value accordingly to bring the next set of required data on screen.
transformGroup.Children.Add(New TranslateTransform() With {.Y = -(pageIndex * pageHeight)})
Then once the number of needed pages is reached, tell the printer to stop
'sets if there is more than 1 page to print
If pagesLeft <= 0 Then
e.HasMorePages = False
Exit Sub
Else
e.HasMorePages = True
End If
Or if this is too much work, you can simply just scale all the notes to fit onto screen. Again probably by converting to UI element.
Hope this helps

Printing WPF - no paging, adjust page size instead

I have a till roll printer and I want to print on it. I don't need paging but I do need to adjust the page size instead. No matter what code I use the printer page size always uses the settings in the Printer Preferences.
PrinterSettings ps = new PrinterSettings();
ps.DefaultPageSettings.PaperSize = new PaperSize("rec", 200, 900);
System.Windows.Controls.PrintDialog printDialog = new PrintDialog();
MyPaginator paginator = new MyPaginator(print);
paginator.PageSize = new Size(200, 900);
printDialog.PrintDocument(paginator, "My Receipt");
I'm using a DocumentPaginator as I thought this would allow be to be more specific about the page I wanted to print.
How can I set the page size?

Snapshots of Control in time using VisualBrush stored in one Fixed(Flow)Document

I need to take snapshots of Control in time and store them in one FixedDocument. Problem is that VisualBrush is somehow "lazy" and do not evaluate itself by adding it to document. When I finaly create the document, all pages contains the same (last) state of Control. While VisualBrush cannot be Freezed, is there any other chance to do it? I would like to have more snapshots on one page so generate document page by page isn't solution for me. Aswel as converting VisualBrush to Bitmap (I want to keep it in vectors). In short - I need to somehow Freeze() VisualBrush
for(;;)
{
FixedPage page = new FixedPage();
...
Rectangle rec = new Rectangle();
...
rec.Fill = vb;
page.Children.Add(rec);
PageContent content = new PageContent();
((IAddChild)content).AddChild(page);
doc.Pages.Add(content);
}
I used serialization:
string svb = XamlWriter.Save(vb.CloneCurrentValue());
// Replace all "Name" attributes (I don't need them already and deserialization would crash on them) with "Tag" - not best practice but it's fast :)
svb = svb.Replace("Name", "Tag");
rect.Fill((VisualBrush)XamlReader.Parse(svb));
EDIT
Better way is to save Visual as XPS document and then take the Visual back. (De)serialization has some problems with SharedSizeGroups and many other "reference like" things.
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
control.InvalidateArrange();
UpdateLayout();
writer.Write(control);
Visual capture = doc.GetFixedDocumentSequence().DocumentPaginator.GetPage(0).Visual;

Best way to show huge text in WPF?

I need to show a really huge amount of text data in WPF code. First i tried to use TextBox (and of course it was too slow in rendering). Now i'm using FlowDocument--and its awesome--but recently i have had another request: text shouldnt be hyphenated. Supposedly it is not (document.IsHyphenationEnabled = false) but i still don't see my precious horizontal scroll bar. if i magnify scale text is ... hyphenated.
public string TextToShow
{
set
{
Paragraph paragraph = new Paragraph();
paragraph.Inlines.Add(value);
FlowDocument document = new FlowDocument(paragraph);
document.IsHyphenationEnabled = false;
flowReader.Document = document;
flowReader.IsScrollViewEnabled = true;
flowReader.ViewingMode = FlowDocumentReaderViewingMode.Scroll;
flowReader.IsPrintEnabled = true;
flowReader.IsPageViewEnabled = false;
flowReader.IsTwoPageViewEnabled = false;
}
}
That's how i create FlowDocument - and here comes part of my WPF control:
<FlowDocumentReader Name="flowReader" Margin="2 2 2 2" Grid.Row="0" />
Nothing criminal =))
I'd like to know how to tame this beast - googled nothing helpful. Or you have some alternative way to show megabytes of text, or textbox have some virtualization features which i need just to enable. Anyway i'll be happy to hear your response!
It's really wrapping not hyphenation. And one can overcome this by setting FlowDocument.PageWidth to reasonable value, the only question was how to determine this value.
Omer suggested this recipe msdn.itags.org/visual-studio/36912/ but i dont like using TextBlock as an measuring instrument for text. Much better way:
Paragraph paragraph = new Paragraph();
paragraph.Inlines.Add(value);
FormattedText text = new FormattedText(value, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(paragraph.FontFamily, paragraph.FontStyle, paragraph.FontWeight, paragraph.FontStretch), paragraph.FontSize, Brushes.Black );
FlowDocument document = new FlowDocument(paragraph);
document.PageWidth = text.Width*1.5;
document.IsHyphenationEnabled = false;
Omer - thanks for the direction.

Resources