How can I check if user has cancelled printing from printing queue? - c#

I am trying to print a WPF component through XPS document writer, There are lots of pages (in 100). It takes lot of time to print. That is why I used Thread.Sleep to simulate that. While printing those pages. User can cancel the print from print queue of windows. I can print it easily but if user cancel it. It throws an exception at
collator.EndBatchWrite();
Exception Message
private void Print_Click(object sender, RoutedEventArgs e)
{
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
PrintQueue printQueue = printDialog.PrintQueue;
XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
SerializerWriterCollator collator = writer.CreateVisualsCollator();
collator.BeginBatchWrite();
collator.Write(VisualLE());
Thread.Sleep(20000);
collator.Write(VisualLE());
collator.EndBatchWrite();
}
}
private static ContainerVisual VisualLE()
{
ContainerVisual newPage = new ContainerVisual();
FixedPage fixedPage;
Border border = new Border();
border.Height = 400;
border.Width = 400;
border.BorderThickness = new Thickness(1);
border.BorderBrush = new SolidColorBrush(Color.FromRgb(1, 1, 1));
fixedPage = new FixedPage();
Size size = new Size(600, 600);
fixedPage.Height = size.Height;
fixedPage.Width = size.Width;
fixedPage.Children.Add(border);
fixedPage.Measure(size);
fixedPage.Arrange(new Rect(new Point(), size));
fixedPage.UpdateLayout();
newPage.Children.Add(fixedPage);
return newPage;
}
Printing Queue

Related

Printing a Windows Form fit to an A4 Paper [duplicate]

In C#, I am trying to print an image using PrintDocument class with the below code. The image is of size 1200 px width and 1800 px height. I am trying to print this image in a 4*6 paper using a small zeebra printer. But the program is printing only 4*6 are of the big image. that means it is not adjusting the image to the paper size !
PrintDocument pd = new PrintDocument();
pd.PrintPage += (sender, args) =>
{
Image i = Image.FromFile("C://tesimage.PNG");
Point p = new Point(100, 100);
args.Graphics.DrawImage(i, 10, 10, i.Width, i.Height);
};
pd.Print();
When i print the same image using Window Print (right click and select print, it is scaling automatically to paper size and printing correctly. that means everything came in 4*6 paper.) How do i do the same in my C# program ?
The parameters that you are passing into the DrawImage method should be the size you want the image on the paper rather than the size of the image itself, the DrawImage command will then take care of the scaling for you. Probably the easiest way is to use the following override of the DrawImage command.
args.Graphics.DrawImage(i, args.MarginBounds);
Note: This will skew the image if the proportions of the image are not the same as the rectangle. Some simple math on the size of the image and paper size will allow you to create a new rectangle that fits in the bounds of the paper without skewing the image.
Not to trample on BBoy's already decent answer, but I've done the code that maintains aspect ratio. I took his suggestion, so he should get partial credit here!
PrintDocument pd = new PrintDocument();
pd.DefaultPageSettings.PrinterSettings.PrinterName = "Printer Name";
pd.DefaultPageSettings.Landscape = true; //or false!
pd.PrintPage += (sender, args) =>
{
Image i = Image.FromFile(#"C:\...\...\image.jpg");
Rectangle m = args.MarginBounds;
if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
{
m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
}
else
{
m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
}
args.Graphics.DrawImage(i, m);
};
pd.Print();
The solution provided by BBoy works fine. But in my case I had to use
e.Graphics.DrawImage(memoryImage, e.PageBounds);
This will print only the form. When I use MarginBounds it prints the entire screen even if the form is smaller than the monitor screen. PageBounds solved that issue. Thanks to BBoy!
You can use my code here
//Print Button Event Handeler
private void btnPrint_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += PrintPage;
//here to select the printer attached to user PC
PrintDialog printDialog1 = new PrintDialog();
printDialog1.Document = pd;
DialogResult result = printDialog1.ShowDialog();
if (result == DialogResult.OK)
{
pd.Print();//this will trigger the Print Event handeler PrintPage
}
}
//The Print Event handeler
private void PrintPage(object o, PrintPageEventArgs e)
{
try
{
if (File.Exists(this.ImagePath))
{
//Load the image from the file
System.Drawing.Image img = System.Drawing.Image.FromFile(#"C:\myimage.jpg");
//Adjust the size of the image to the page to print the full image without loosing any part of it
Rectangle m = e.MarginBounds;
if ((double)img.Width / (double)img.Height > (double)m.Width / (double)m.Height) // image is wider
{
m.Height = (int)((double)img.Height / (double)img.Width * (double)m.Width);
}
else
{
m.Width = (int)((double)img.Width / (double)img.Height * (double)m.Height);
}
e.Graphics.DrawImage(img, m);
}
}
catch (Exception)
{
}
}
Answer:
public void Print(string FileName)
{
StringBuilder logMessage = new StringBuilder();
logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ START - {0} - {1} -------------------]", MethodBase.GetCurrentMethod(), DateTime.Now.ToShortDateString()));
logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "Parameter: 1: [Name - {0}, Value - {1}", "None]", Convert.ToString("")));
try
{
if (string.IsNullOrWhiteSpace(FileName)) return; // Prevents execution of below statements if filename is not selected.
PrintDocument pd = new PrintDocument();
//Disable the printing document pop-up dialog shown during printing.
PrintController printController = new StandardPrintController();
pd.PrintController = printController;
//For testing only: Hardcoded set paper size to particular paper.
//pd.PrinterSettings.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);
//pd.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);
pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
pd.PrinterSettings.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
pd.PrintPage += (sndr, args) =>
{
System.Drawing.Image i = System.Drawing.Image.FromFile(FileName);
//Adjust the size of the image to the page to print the full image without loosing any part of the image.
System.Drawing.Rectangle m = args.MarginBounds;
//Logic below maintains Aspect Ratio.
if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
{
m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
}
else
{
m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
}
//Calculating optimal orientation.
pd.DefaultPageSettings.Landscape = m.Width > m.Height;
//Putting image in center of page.
m.Y = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Height - m.Height) / 2);
m.X = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Width - m.Width) / 2);
args.Graphics.DrawImage(i, m);
};
pd.Print();
}
catch (Exception ex)
{
log.ErrorFormat("Error : {0}\n By : {1}-{2}", ex.ToString(), this.GetType(), MethodBase.GetCurrentMethod().Name);
}
finally
{
logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ END - {0} - {1} -------------------]", MethodBase.GetCurrentMethod().Name, DateTime.Now.ToShortDateString()));
log.Info(logMessage.ToString());
}
}
Agree with TonyM and BBoy - this is the correct answer for original 4*6 printing of label. (args.PageBounds). This worked for me for printing Endicia API service shipping Labels.
private void SubmitResponseToPrinter(ILabelRequestResponse response)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += (sender, args) =>
{
Image i = Image.FromFile(response.Labels[0].FullPathFileName.Trim());
args.Graphics.DrawImage(i, args.PageBounds);
};
pd.Print();
}
all these answers has the problem, that's always stretching the image to pagesize and cuts off some content at trying this.
Found a little bit easier way.
My own solution only stretch(is this the right word?) if the image is to large, can use multiply copies and pageorientations.
PrintDialog dlg = new PrintDialog();
if (dlg.ShowDialog() == true)
{
BitmapImage bmi = new BitmapImage(new Uri(strPath));
Image img = new Image();
img.Source = bmi;
if (bmi.PixelWidth < dlg.PrintableAreaWidth ||
bmi.PixelHeight < dlg.PrintableAreaHeight)
{
img.Stretch = Stretch.None;
img.Width = bmi.PixelWidth;
img.Height = bmi.PixelHeight;
}
if (dlg.PrintTicket.PageBorderless == PageBorderless.Borderless)
{
img.Margin = new Thickness(0);
}
else
{
img.Margin = new Thickness(48);
}
img.VerticalAlignment = VerticalAlignment.Top;
img.HorizontalAlignment = HorizontalAlignment.Left;
for (int i = 0; i < dlg.PrintTicket.CopyCount; i++)
{
dlg.PrintVisual(img, "Print a Image");
}
}

How To print a long string into multiple pages in C#

I'm trying to print a very long string using code below but it prints the whole text only in one page. Is there any easy way to print it correctly?
string text="the text has like 1000 words";
System.Drawing.Printing.PrintDocument p = new System.Drawing.Printing.PrintDocument();
p.PrintPage += delegate (object sender1, System.Drawing.Printing.PrintPageEventArgs e1)
{
e1.Graphics.DrawString(text, new System.Drawing.Font("Times New Roman", 12), new System.Drawing.SolidBrush(System.Drawing.Color.Black), new System.Drawing.RectangleF(50, 50, p.DefaultPageSettings.PrintableArea.Width - 50, p.DefaultPageSettings.PrintableArea.Height - 50));
};
try
{
p.Print();
}
catch (Exception ex)
{
throw new Exception("Exception Occured While Printing", ex);
}
I tried to solve it with this article but the method stuck in some loop that I don't know how to fix.
You have to keep in mind that PrintDocument will raise the event PrintPage as long as you tell it there are more pages. It is your task to keep track of what is printed, what needs to printed next and if you need another page or not.
There are several ways to accomplish that. I have chosen in this case to take the content of your text, check how much of it fits on the current page, DrawString that bit and then update my processing string, called remainingtext to be able to repeat for the next Page. The decision if a next page is needed is controlled by setting HasMorepages of the PrintEvent arguments instance to true or false when we're done.
Here is the code:
PrintDocument p = new PrintDocument();
var font = new Font("Times New Roman", 12);
var margins = p.DefaultPageSettings.Margins;
var layoutArea = new RectangleF(
margins.Left,
margins.Top,
p.DefaultPageSettings.PrintableArea.Width - (margins.Left + margins.Right ),
p.DefaultPageSettings.PrintableArea.Height - (margins.Top + margins.Bottom));
var layoutSize = layoutArea.Size;
layoutSize.Height = layoutSize.Height - font.GetHeight(); // keep lastline visible
var brush = new SolidBrush(Color.Black);
// what still needs to be printed
var remainingText = text;
p.PrintPage += delegate (object sender1, PrintPageEventArgs e1)
{
int charsFitted, linesFilled;
// measure how many characters will fit of the remaining text
var realsize = e1.Graphics.MeasureString(
remainingText,
font,
layoutSize,
StringFormat.GenericDefault,
out charsFitted, // this will return what we need
out linesFilled);
// take from the remainingText what we're going to print on this page
var fitsOnPage = remainingText.Substring(0, charsFitted);
// keep what is not printed on this page
remainingText = remainingText.Substring(charsFitted).Trim();
// print what fits on the page
e1.Graphics.DrawString(
fitsOnPage,
font,
brush,
layoutArea);
// if there is still text left, tell the PrintDocument it needs to call
// PrintPage again.
e1.HasMorePages = remainingText.Length > 0;
};
p.Print();
When I hookup an PrintPreviewControl this is the result:
So thanks to rene I figured it out how to print it correctly. I edit his code and the difference here is that the user chooses the paper size and rectangel drawing happens with choosen paper margin size. This is a ready printing method in case you want to use it...
private void Print(string thetext){
try
{
System.Drawing.Printing.PrintDocument p = new System.Drawing.Printing.PrintDocument();
var font = new Font("Times New Roman", 12);
var brush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
// what still needs to be printed
var remainingText = theText;
p.PrintPage += delegate (object sender1, System.Drawing.Printing.PrintPageEventArgs e1)
{
int charsFitted, linesFilled;
// measure how many characters will fit of the remaining text
var realsize = e1.Graphics.MeasureString(
remainingText,
font,
e1.MarginBounds.Size,
System.Drawing.StringFormat.GenericDefault,
out charsFitted, // this will return what we need
out linesFilled);
// take from the remainingText what we're going to print on this page
var fitsOnPage = remainingText.Substring(0, charsFitted);
// keep what is not printed on this page
remainingText = remainingText.Substring(charsFitted).Trim();
// print what fits on the page
e1.Graphics.DrawString(
fitsOnPage,
font,
brush,
e1.MarginBounds);
// if there is still text left, tell the PrintDocument it needs to call
// PrintPage again.
e1.HasMorePages = remainingText.Length > 0;
};
System.Windows.Forms.PrintDialog pd = new System.Windows.Forms.PrintDialog();
pd.Document = p;
DialogResult result = pd.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
p.Print();
}
}catch(Exception e2)
{
System.Windows.MessageBox.Show(e2.Message, "Unable to print",MessageBoxButton.OK);
}
}
Code snippet for "when user clicked 'btnPrint' button, print 'rtbEditor' rich textbox's text.":
private void btnPrint_Click(object sender, EventArgs e) {
var d = new PrintDialog();
d.Document = new PrintDocument();
d.Document.PrintPage += Dd_PrintPage;
remainingText = rtbEditor.Text;
var res = d.ShowDialog();
try { if (res == DialogResult.OK) d.Document.Print(); }
catch { }
}
string remainingText;
private void Dd_PrintPage(object sender, PrintPageEventArgs e){
//this code was for 1 page
//e.Graphics.DrawString(rtbEditor.Text,new Font("Comic Sans MS", 12f),Brushes.Black,new PointF(10,10));
//this is for multiple pages
PrintDocument p = ((PrintDocument)sender);
var font = new Font("Times New Roman", 12);
var margins = p.DefaultPageSettings.Margins;
var layoutArea = new RectangleF(
margins.Left,
margins.Top,
p.DefaultPageSettings.PrintableArea.Width - (margins.Left + margins.Right),
p.DefaultPageSettings.PrintableArea.Height - (margins.Top + margins.Bottom));
var layoutSize = layoutArea.Size;
layoutSize.Height = layoutSize.Height - font.GetHeight(); // keep lastline visible
var brush = new SolidBrush(Color.Black);
int charsFitted, linesFilled;
// measure how many characters will fit of the remaining text
var realsize = e.Graphics.MeasureString(
remainingText,
font,
layoutSize,
StringFormat.GenericDefault,
out charsFitted, // this will return what we need
out linesFilled);
// take from the remainingText what we're going to print on this page
var fitsOnPage = remainingText.Substring(0, charsFitted);
// keep what is not printed on this page
remainingText = remainingText.Substring(charsFitted).Trim();
// print what fits on the page
e.Graphics.DrawString(
fitsOnPage,
font,
brush,
layoutArea);
// if there is still text left, tell the PrintDocument it needs to call
// PrintPage again.
e.HasMorePages = remainingText.Length > 0;
}

WPF FixedPage with same instance of UserControl

First off, I'm not sure if I phrased the title correctly. There are UserControls which are added via a ViewModel and I find them by searching the VisualTree and add them to a ObservableCollection<Grid>. What I would like to do is Print each instance of the UserControl that I retrieve from the VisualTree into a FixedDocument but with each UserControl being on a single page until it fills that page and moves on to the next page.
Here is the code for my current Print Button Click Event:
private async void btnPrint_Click(object sender, RoutedEventArgs e)
{
try
{
if (tabMain.Items.Count > 0)
{
tab = new TabLayout();
tab.Payslip = new ObservableCollection<Grid>();
foreach (var grid in FindVisualChildren<Grid>(this))
{
if (grid.Name == "pdfFile")
{
tab.Payslip.Add(grid);
}
}
FrameworkElement toPrint = new FrameworkElement();
PrintDialog printDialog = new PrintDialog();
PrintCapabilities capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
Size pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
Size visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
FixedDocument fixedDoc = new FixedDocument();
StackPanel panel = new StackPanel(); //was trying to stack them in a stackpanel first but it threw an exception about same instance of usercontrol blah blah...
foreach (var doc in tab.Payslip.ToList())
{
double yOffset = 0;
doc.Measure((new Size(double.PositiveInfinity, double.PositiveInfinity)));
doc.Arrange(new Rect(new Point(0, 0), doc.DesiredSize));
Size size = doc.DesiredSize;
while (yOffset < size.Height)
{
VisualBrush vb = new VisualBrush(doc);
vb.Stretch = Stretch.None;
vb.AlignmentX = AlignmentX.Left;
vb.AlignmentY = AlignmentY.Top;
vb.ViewboxUnits = BrushMappingMode.Absolute;
vb.TileMode = TileMode.None;
vb.Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height);
FixedPage page = new FixedPage();
PageContent pageContent = new PageContent();
((IAddChild)pageContent).AddChild(page);
fixedDoc.Pages.Add(pageContent);
page.Width = fixedDoc.DocumentPaginator.PageSize.Width;
page.Height = fixedDoc.DocumentPaginator.PageSize.Height;
Canvas canvas = new Canvas();
FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
canvas.Width = visibleSize.Width;
canvas.Height = visibleSize.Height;
canvas.Background = vb;
page.Children.Add(canvas);
yOffset += visibleSize.Height;
}
}
//printDialog.PrintDocument(fixedDoc.DocumentPaginator, "");
ShowPrintPreview(fixedDoc);
}
}
catch(Exception ex)
{
var exceptionDialog = new MessageDialog
{
Message = { Text = ex.ToString() }
};
await DialogHost.Show(exceptionDialog, "RootDialog");
}
}
This is how it looks when I try printing three Tabs (UserControls are hosted in Tabs):
As you can see here it prints three separate pages
I want all three on one page and if I print 10 tabs, then it should fill the first page and go on to the next page.
The last time I asked a similar question I was questioned on whether I wrote the code. Bits and pieces of this code came from similar FixedDocument questions on StackOverflow but it has been edited to the point where it actually works for me. So yes I know that the FixedPage reference inside the foreach is whats causing the creation of the three separate pages and I do understand the code.
Summary:
What I want to know is how to get the UserControls from each Tab, onto a single page until its full, without getting the "Specified element is already the logical child of another element. Disconnect it first." error.
I ended up using ItemsControl to hold my ObservableCollection of Controls as a list and print from the ItemsControl using this XpsDocumentWriter method.
public void PrintItemsTo(ItemsControl ic, String jobName)
{
PrintDialog dlg = new PrintDialog();
dlg.UserPageRangeEnabled = true;
if (dlg.ShowDialog().GetValueOrDefault())
{
PageRange range = dlg.PageRange;
// range check - user selection starts from 1
if (range.PageTo > ic.Items.Count)
range.PageTo = ic.Items.Count;
dlg.PrintQueue.CurrentJobSettings.Description = jobName;
XpsDocumentWriter xdw = PrintQueue.CreateXpsDocumentWriter(dlg.PrintQueue);
if (dlg.UserPageRangeEnabled == false || range.PageTo < range.PageFrom)
WriteAllItems(ic, xdw);
else
WriteSelectedItems(ic, xdw, range);
}
}
private void WriteAllItems(ItemsControl ic, XpsDocumentWriter xdw)
{
PageRange range = new PageRange(1, ic.Items.Count);
WriteSelectedItems(ic, xdw, range);
}
private void WriteSelectedItems(ItemsControl ic, XpsDocumentWriter xdw, PageRange range)
{
IItemContainerGenerator generator = ic.ItemContainerGenerator;
// write visuals using a batch operation
VisualsToXpsDocument collator = (VisualsToXpsDocument)xdw.CreateVisualsCollator();
collator.BeginBatchWrite();
if (WritePageRange(collator, generator, range))
collator.EndBatchWrite();
}
private bool WritePageRange(VisualsToXpsDocument collator, IItemContainerGenerator generator, PageRange range)
{
// Get the generator position of the first data item
// PageRange reflects user's selection starts from 1
GeneratorPosition startPos = generator.GeneratorPositionFromIndex(range.PageFrom - 1);
// If PageFrom > PageTo, print in reverse order
// UPDATE: never occurs; PrintDialog always 'normalises' the PageRange
GeneratorDirection direction = (range.PageFrom <= range.PageTo) ? GeneratorDirection.Forward : GeneratorDirection.Backward;
using (generator.StartAt(startPos, direction, true))
{
for (int numPages = Math.Abs(range.PageTo - range.PageFrom) + 1; numPages > 0; --numPages)
{
bool newlyRealized;
// Get or create the child
UIElement next = generator.GenerateNext(out newlyRealized) as UIElement;
if (newlyRealized)
{
generator.PrepareItemContainer(next);
}
// The collator doesn't like ContentPresenters and produces blank pages
// for pages 2-n. Finding the child of the ContentPresenter and writing
// that solves seems to solve the problem
if (next is ContentPresenter)
{
ContentPresenter presenter = (ContentPresenter)next;
presenter.UpdateLayout();
presenter.ApplyTemplate(); // not sure if this is necessary
DependencyObject child = VisualTreeHelper.GetChild(presenter, 0);
if (child is UIElement)
next = (UIElement)child;
}
try
{
collator.Write(next);
}
catch
{
// if user prints to Microsoft XPS Document Writer
// and cancels the SaveAs dialog, we get an exception.
return false;
}
}
}
return true;
}
PrintItemsTo(), displays a PrintDialog to print to any printer while WriteAllItems displays a Dialog to save as PDF.

How to print a panel in WinFormc#?

I have a panel which have labels and a datagridview. I'm trying to print the panel with its contents using this code
PrintDialog myPrintDialog = new PrintDialog();
System.Drawing.Bitmap memoryImage = new System.Drawing.Bitmap(panel2.Width, panel2.Height);
panel2.DrawToBitmap(memoryImage, panel2.ClientRectangle);
myPrintDialog.ShowDialog();
System.Drawing.Printing.PrinterSettings values;
values = myPrintDialog.PrinterSettings;
myPrintDialog.Document = printDocument1;
printDocument1.PrintController = new StandardPrintController();
printDocument1.Print();
printDocument1.Dispose();
But it prints nothing. I remove the datagridview but still prints nothing. Then I change the panel back color but again it prints white page. Kindly Guide me How I do this?
Add this code to PrintPage event and call the Print() method from PrintDocument class object
private void doc_PrintPage(object sender, PrintPageEventArgs e)
{
float x = e.MarginBounds.Left;
float y = e.MarginBounds.Top;
Bitmap bmp = new Bitmap(panel2.Width, panel2.Height);
panel2.DrawToBitmap(bmp, new Rectangle(0, 0, panel2.Width, panel2.Height));
e.Graphics.DrawImage((Image)bmp, x, y);
}
Call the method like this
PrintDocument doc = new PrintDocument();
doc.PrintPage += this.doc_PrintPage;
PrintDialog dlg = new PrintDialog();
dlg.Document = doc;
if (dlg.ShowDialog() == DialogResult.OK)
{
doc.Print();
}

Showing Print Preview in C#

Right now, I'm trying to build my form on a PrintDocument, but the only way for me to see where stuff is actually appearing on the page is to print a paper. It works, but I have a lot of stuff I need to add, and I'd rather not waste tons of paper. Right now I have a print dialogue come up, but theres no print preview button. Is there a way I can make one appear? Thanks!
public partial class Form4 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components;
private System.Windows.Forms.Button printButton;
public Form4()
{
// The Windows Forms Designer requires the following call.
InitializeComponent();
}
// The Click event is raised when the user clicks the Print button.
private void printButton_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
PrintDialog pdi = new PrintDialog();
pdi.Document = pd;
if (pdi.ShowDialog() == DialogResult.OK)
{
pd.Print();
}
}
// The PrintPage event is raised for each page to be printed.
private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
Single yPos = 0;
Single leftMargin = e.MarginBounds.Left;
Single topMargin = e.MarginBounds.Top;
Image img = Image.FromFile("logo.bmp");
Rectangle logo = new Rectangle(40, 40, 50, 50);
using (Font printFont = new Font("Arial", 20.0f))
{
e.Graphics.DrawImage(img, logo);
e.Graphics.DrawString("Header", printFont, Brushes.Black, leftMargin, yPos, new StringFormat());
}
using (SolidBrush blueBrush = new SolidBrush(Color.Black))
{
Rectangle rect = new Rectangle(100, 100, 500, 120);
e.Graphics.FillRectangle(blueBrush, rect);
}
}
// The Windows Forms Designer requires the following procedure.
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.printButton = new System.Windows.Forms.Button();
this.ClientSize = new System.Drawing.Size(504, 381);
this.Text = "Print Example";
printButton.ImageAlign =
System.Drawing.ContentAlignment.MiddleLeft;
printButton.Location = new System.Drawing.Point(32, 110);
printButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
printButton.TabIndex = 0;
printButton.Text = "Print the file.";
printButton.Size = new System.Drawing.Size(136, 40);
printButton.Click += new System.EventHandler(printButton_Click);
this.Controls.Add(printButton);
}
}
You can use a PrintPreviewDialog for this:
private void printButton_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
PrintDialog printdlg = new PrintDialog();
PrintPreviewDialog printPrvDlg = new PrintPreviewDialog();
// preview the assigned document or you can create a different previewButton for it
printPrvDlg.Document = pd;
printPrvDlg.ShowDialog(); // this shows the preview and then show the Printer Dlg below
printdlg.Document = pd;
if (printdlg.ShowDialog() == DialogResult.OK)
{
pd.Print();
}
}

Categories