How to get this UI output in printout? - c#

I am working on WPF application.Here i have to work on some print formats.To solve paging issue for print i am using the following code :
private void Button_Click(object sender, RoutedEventArgs e)
{
// Create a PrintDialog
PrintDialog printDlg = new PrintDialog();
// Create a FlowDocument dynamically.
FlowDocument doc = CreateFlowDocument();
doc.Name = "FlowDoc";
doc.PageHeight = printDlg.PrintableAreaHeight;
doc.PageWidth = printDlg.PrintableAreaWidth;
// Create IDocumentPaginatorSource from FlowDocument
IDocumentPaginatorSource idpSource = doc;
// Call PrintDocument method to send document to printer
printDlg.PrintDocument(idpSource.DocumentPaginator, "Hello WPF Printing.");
}
and
private FlowDocument CreateFlowDocument()
{
// Create a FlowDocument
FlowDocument doc = new FlowDocument();
int i = 0;
while (i <2)
{
// Create first Paragraph
Paragraph p1 = new Paragraph();
MyUserControl comp = new MyUserControl ();
p1.BorderBrush = new SolidColorBrush(Color.FromRgb(79, 129, 189));
p1.BorderThickness = new Thickness(3);
p1.Inlines.Add(comp);
// Add Paragraph to Section
doc.Blocks.Add(p1);
// Add Section to FlowDocument
//doc.Blocks.Add(sec);
i++;
}
return doc;
}
this code works fine for me.
Problem :
I just have problem with UI which i am getting using this code.
This is the print which i am getting now on paper :
and this is the print which i require on paper:
Please provide some idea and code so that i can clear this problem.
Thanks in advance.

Related

MigraDoc: Rendering the same document twice

I want to render a "Document"-object twice, but on the second generation the PDF-File shows an error:
Error on this page. Maybe this page couldn't appear correctly. Please talk to the document-creator.
Sorry, it is german...
This is my example-code:
using System;
using System.Windows.Forms;
using MigraDoc.Rendering;
using MigraDoc.DocumentObjectModel;
using PdfSharp.Pdf;
using System.Diagnostics;
namespace Temp
{
public partial class Form1 : Form
{
Document document; //using the same document- and renderer-object ..
PdfDocumentRenderer renderer; //..creates the error
public Form1()
{
InitializeComponent();
document = new Document();
renderer = new PdfDocumentRenderer(false, PdfFontEmbedding.Always);
}
private void button1_Click(object sender, EventArgs e)
{
Section section = document.AddSection();
Paragraph paragraph = section.AddParagraph();
paragraph.AddFormattedText("Hello World", TextFormat.Bold);
SaveFile(renderer);
}
private void SaveFile(PdfDocumentRenderer renderer)
{
renderer.Document = document;
renderer.RenderDocument();
string pdfFilename = string.Format("Rekla-{0:dd.MM.yyyy_hh-mm-ss}.pdf", DateTime.Now);
renderer.PdfDocument.Save(pdfFilename);
Process.Start(pdfFilename);
}
}
}
Of course i could always create a new "Document"-object:
private void button1_Click(object sender, EventArgs e)
{
Document document = new Document(); //Creating a new document-object solves the problem..
PdfDocumentRenderer renderer = new PdfDocumentRenderer(false, PdfFontEmbedding.Always);
Section section = document.AddSection();
Paragraph paragraph = section.AddParagraph();
paragraph.AddFormattedText("Hi", TextFormat.Bold);
SaveFile(renderer, document);
}
This works. But i need to change the current document while performing other button-click-events. The second code-snippet doesn't solve this task.
Does someone know how to fix the first code-snippet?
Do not re-use the Renderer. Create a new Renderer in the SaveFile method and everything should be fine.
If a new Renderer is not enough, call document.Clone() and assign that to the Renderer.
A method I have found very useful for repeatedly saving a Migradoc pdf to a file is to save the document to a MemoryStream/byte array when I render it. Then when I need to save the pdf file, I just save the byte array.
Put this part in your constructor where you want to render the document:
// First we render our document and save it to a byte array
bytes[] documentBytes;
Document doc;
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
PdfDocumentRenderer pdfRender = new PdfDocumentRenderer();
pdfRender.Document = doc;
pdfRender.RenderDocument();
pdfRender.Save(ms, false);
documentBytes = ms.ToArray();
}
Put this part in your button event where you want to save to a file:
// Then we save the byte array to a file when needed
string filename;
using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Create))
{
fs.Write(documentBytes, 0, documentBytes.Length);
}

Set margin to printing document while wpf control is printing

I am trying to print a treeview control in wpf using the following code
PrintDialog printDlg = new PrintDialog();
printDlg.PrintVisual(trv, "GTree Printing.");
The treeview is printing, but it prints to right side and some data is cutting off. How do I set margin in this case? Also It won't print the entire tree structure, only the visible portion is printing. Please do advise on this.
This is in desktop application
Thanks,
Sivajith
public static void Print(IEnumerable<UIElement> dataForPrint, string printerName)
{
try
{
var printDialog = new PrintDialog();
using (var printQueue = new PrintQueue(new PrintServer(), printerName))
{
printDialog.PrintQueue = printQueue;
var area = printDialog.PrintQueue.GetPrintCapabilities();
if (area.PageImageableArea == null) throw new Exception("Failed to load printer settings.");
var flowDocument = new FlowDocument
{
PagePadding = new Thickness(area.PageImageableArea.OriginWidth, 0, 0, 0),
PageWidth = area.PageImageableArea.ExtentWidth + area.PageImageableArea.OriginWidth
};
foreach (var uiElement in dataForPrint)
{
flowDocument.Blocks.Add(new BlockUIContainer(uiElement));
}
var paginator = ((IDocumentPaginatorSource) flowDocument).DocumentPaginator;
printDialog.PrintDocument(paginator, "A Flow Document");
}
}
catch (NotSupportedException)
{
}
catch (Exception e)
{
Log(e);
}
}
If you show Printer Dialog you haven't to create PrintQueue. Just access to PrintDialog.PrintQueue property

c# printing a windows form application

I found this code to print
// The PrintDialog will print the document
// by handling the document's PrintPage event.
private void document_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
// Insert code to render the page here.
// This code will be called when the control is drawn.
// The following code will render a simple
// message on the printed document.
string text = "In document_PrintPage method.";
System.Drawing.Font printFont = new System.Drawing.Font
("Arial", 35, System.Drawing.FontStyle.Regular);
// Draw the content.
e.Graphics.DrawString(text, printFont,
System.Drawing.Brushes.Black, 10, 10);
}
// Declare the PrintDocument object.
private System.Drawing.Printing.PrintDocument docToPrint =
new System.Drawing.Printing.PrintDocument();
private void printButton_Click(object sender, EventArgs e)
{
PrintDialog PrintDialog1 = new PrintDialog();
// Allow the user to choose the page range he or she would
// like to print.
PrintDialog1.AllowSomePages = true;
// Show the help button.
PrintDialog1.ShowHelp = true;
// Set the Document property to the PrintDocument for
// which the PrintPage Event has been handled. To display the
// dialog, either this property or the PrinterSettings property
// must be set
PrintDialog1.Document = docToPrint;
DialogResult result = PrintDialog1.ShowDialog();
// If the result is OK then print the document.
if (result == DialogResult.OK)
{
docToPrint.Print();
}
}
I execute it and the result of the printing is an empty page, my question is where can i put the data to print? and how can i make the printed data as rows each row has label and value.
You create the PrintDocument as a private member:
// Declare the PrintDocument object.
private System.Drawing.Printing.PrintDocument docToPrint =
new System.Drawing.Printing.PrintDocument();
But that makes it hard to attach the event handler at the right moment. I suggest using the constructor:
// Declare the PrintDocument object.
private System.Drawing.Printing.PrintDocument docToPrint;
//= new System.Drawing.Printing.PrintDocument();
public Form1() // the Form ctor
{
InitializeComponents();
docToPrint = new System.Drawing.Printing.PrintDocument();
docToPrint.PrintPage += document_PrintPage; // the missing piece
}

Print textbox contents in C#

I want to print the contents of a simple TextBox. After I click the print button, PrintDialog is shown.
I found a lot of info but they all use RichTextBoxes. Is there an easy way to do something like this?
This print contents of textbox named textbox1
PrintDocument document = new PrintDocument();
PrintDialog dialog = new PrintDialog();
public Form1()
{
InitializeComponent();
document.PrintPage += new PrintPageEventHandler(document_PrintPage);
}
void document_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawString(textBox1.Text, new Font("Arial", 20, FontStyle.Regular), Brushes.Black, 20, 20);
}
private void btnPrint_Click(object sender, EventArgs e)
{
dialog.Document = document;
if (dialog.ShowDialog() == DialogResult.OK)
{
document.Print();
}
}
Take a look at this: http://answers.yahoo.com/question/index?qid=20081230163003AA4xOaT,
and this: How to print the contents of a TextBox
Also, there is a tutorial on printing in C#: http://www.dreamincode.net/forums/topic/44330-printing-in-c%23/
If, after this, you still cannot print TextBox content from some reason, you can always create a new RichTextBox object and assign your TextBox's Text to its text. Then proceed with printing using the RichTextBox.

How can I get a FlowDocument Hyperlink to launch browser and go to URL in a WPF app?

The following code in a WPF app creates a hyperlink that looks and acts like a hyperlink, but doesn't do anything when clicked.
What do I have to change so that when I click it, it opens the default browser and goes to the specified URL?
alt text http://www.deviantsart.com/upload/4fbnq2.png
XAML:
<Window x:Class="TestLink238492.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel Margin="10">
<ContentControl x:Name="MainArea"/>
</StackPanel>
</Window>
Code Behind:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace TestLink238492
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
FlowDocumentScrollViewer fdsv = new FlowDocumentScrollViewer();
FlowDocument doc = new FlowDocument();
fdsv.Document = doc;
fdsv.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
doc.PagePadding = new Thickness(0);
Paragraph paragraph = new Paragraph();
doc.Blocks.Add(paragraph);
Run run = new Run("this is flow document text and ");
paragraph.Inlines.Add(run);
Run run2 = new Run("this is a hyperlink");
Hyperlink hlink = new Hyperlink(run2);
hlink.NavigateUri = new Uri("http://www.google.com");
paragraph.Inlines.Add(hlink);
StackPanel sp = new StackPanel();
TextBlock tb = new TextBlock();
tb.Text = "this is textblock text";
sp.Children.Add(tb);
sp.Children.Add(fdsv);
MainArea.Content = sp;
}
}
}
I found the answer to this one, you have to add RequestNavigate and handle it yourself:
Run run2 = new Run("this is a hyperlink");
Hyperlink hlink = new Hyperlink(run2);
hlink.NavigateUri = new Uri("http://www.google.com");
hlink.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(hlink_RequestNavigate);
paragraph.Inlines.Add(hlink);
void hlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
Got the solutions for this Poma. The code section below should be added to your class where you need to do this. Or you can put it in a static class somewhere if you need to get to it from multiple files. I've tweaked it slightly for what I'm doing.
#region Activate Hyperlinks in the Rich Text box
//http://stackoverflow.com/questions/5465667/handle-all-hyperlinks-mouseenter-event-in-a-loaded-loose-flowdocument
void SubscribeToAllHyperlinks(FlowDocument flowDocument)
{
var hyperlinks = GetVisuals(flowDocument).OfType<Hyperlink>();
foreach (var link in hyperlinks)
link.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(link_RequestNavigate);
}
public static IEnumerable<DependencyObject> GetVisuals(DependencyObject root)
{
foreach (var child in LogicalTreeHelper.GetChildren(root).OfType<DependencyObject>())
{
yield return child;
foreach (var descendants in GetVisuals(child))
yield return descendants;
}
}
void link_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
//http://stackoverflow.com/questions/2288999/how-can-i-get-a-flowdocument-hyperlink-to-launch-browser-and-go-to-url-in-a-wpf
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
#endregion Activate Hyperlinks in the Rich Text box
You'll call it in your code like this:
string xaml = HTMLConverter.HtmlToXamlConverter.ConvertHtmlToXaml(this.itemControl.NotificationItem.Body, true);
FlowDocument flowDocument = XamlReader.Load(new XmlTextReader(new StringReader(xaml))) as FlowDocument;
SubscribeToAllHyperlinks(flowDocument);
bodyFlowDocument.Document = flowDocument;
All the HTMLConverter stuff can be found at: http://blogs.msdn.com/b/wpfsdk/archive/2006/05/25/606317.aspx
That's if you need to convert HTML to a Flow Document. Although, that's slightly out of the scope of this topic.

Categories