Printing Forms using PrintDocument - c#

I'm trying MSDN's example of printing using PrintDocument, but it's not going so well. I've got it all to compile, but when I hit print, a "Fax Sending Settings" window pops up. Is this supposed to happen? Im trying to print, not send a fax!
What would I have to change to print this straight to the default printer instead?
Thanks!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Printing;
namespace WindowsFormsApplication1
{
public partial class Form4 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components;
private System.Windows.Forms.Button printButton;
private Font printFont;
private StreamReader streamToPrint;
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);
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", 10.0f))
{
e.Graphics.DrawImage(img, logo);
e.Graphics.DrawString("Testing!", printFont, Brushes.Black, leftMargin, yPos, new StringFormat());
}
}
// 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);
}
}
}

It's seems like a fax machine is your default printer, the easiest way to remedy this would be to add a print dialog before printing the page
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument;
//Show Print Dialog
if (printDialog.ShowDialog() == DialogResult.OK)
{
//Print the page
printDocument.Print();
}
This will let the user select their desired printer before printing

Firs you should declare an object of System.Drawing.Printing.PrintDocument:
private System.Drawing.Printing.PrintDocument printDocument = new System.Drawing.Printing.PrintDocument();
Then add the code described in the previous answer:
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument;
//Show Print Dialog
if (printDialog.ShowDialog() == DialogResult.OK)
{
//Print the page
printDocument.Print();
}

Related

C# PrintPage function from another class

Problem
I have an issue with moving the PrintPage function (SampleForm_PrintPage) to a new class (PrintPageDesign) also design of the PrintPage uses data from the main form and i have not been able to pull the data in to the new class.
Why?
I'm moving all PrintPage functions to individual classes as there are multiple page designs required in the application, having them all in the same main form seems hard to review and update when each page design requires any change.
Sample Code
To simplify my problem i have created a sample solution in visual basic,
Form1.cs (form code):
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace Sample_Print
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
private void BTN_Print_Click(object sender, EventArgs e)
{
PrintDialog PD_SamplePage = new PrintDialog();
PrintDocument Doc_SamplePage = new PrintDocument();
Doc_SamplePage.PrintPage += SampleForm_PrintPage;
PD_SamplePage.Document = Doc_SamplePage;
Doc_SamplePage.Print();
}
protected void SampleForm_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
e.Graphics.CompositingMode = CompositingMode.SourceOver;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
e.Graphics.DrawString(TB_Name.Text.ToString(), new Font("Roboto Condensed",12, FontStyle.Bold), Brushes.Black, 10, 10);
}
}
}
Requirement
i would like to move function
SampleForm_PrintPage
to class PrintPageDesign , currently there is only visual studio generated code is in the class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sample_Print
{
class PrintPageDesign
{
}
}
i have tried several ways to get the value from the text box outside of the main form but resulted in null.
any help is highly appreciated.
As commented above, you can use partial classes to separate the Main Form members, methods and functionalities.
Press Shift+Alt+C to add a new class. Rename the file to PrintPageDesign and hit Add.
In the new class, add the partial modifier and change the name to Main (the exact name of the main Form). Note, we are creating a partial class here and not deriving from the Main form.
Now you are within the Main Form context and you can access its members.
Example
The Main Form class:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace Sample_Print
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
private void BTN_Print_Click(object sender, EventArgs e) => PrintJob1();
}
}
The PrintPageDesign class:
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using System.ComponentModel;
namespace Sample_Print
{
partial class Main
{
private void PrintJob1(bool preview = false)
{
using (var doc = new PrintDocument())
{
doc.PrintPage += (s, e) =>
{
var g = e.Graphics;
var r = new Rectangle(e.MarginBounds.X, e.MarginBounds.Y,
e.MarginBounds.Width, 32);
using (var sf = new StringFormat())
using (var fnt = new Font("Roboto Condensed", 12, FontStyle.Bold))
{
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(TB_Name.Text, fnt, Brushes.Black, r, sf);
r.Y += r.Height;
foreach (Control c in Controls)
{
g.DrawString(c.Name, fnt, Brushes.Black, r, sf);
r.Y += r.Height;
}
// ...
}
};
if (preview)
using (var ppd = new PrintPreviewDialog() { Document = doc })
ppd.ShowDialog();
else
{
using (var pd = new PrintDialog() { Document = doc })
{
if (pd.ShowDialog() == DialogResult.OK)
pd.Document.Print();
}
}
}
}
}
}

ToolStripControlHost's AutoSize does not function correctly

In the code below, I tried to display a popup above the button when the button is pressed, but the AutoSize of ToolStripControlHost does not work properly and the entire contents are not displayed.
In addition to that, the popup is displayed slightly above the button, even though the button location is specified.
How can I solve this problem?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp7
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var panel1 = new Panel();
var label1 = new Label();
label1.Text = "12345\nabsde\nlllllllllllllllllA\nVWXYZ\nZZZZZZZZZZZZZZA";
label1.BackColor = Color.Red;
label1.Margin = Padding.Empty;
label1.AutoSize = true;
label1.Size = Size.Empty;
label1.Location = new Point(0, 0);
panel1.Controls.Add(label1);
var toolStripControlHost = new ToolStripControlHost(panel1);
toolStripControlHost.Margin = Padding.Empty;
toolStripControlHost.Padding = Padding.Empty;
toolStripControlHost.BackColor = SystemColors.Info;
toolStripControlHost.AutoSize = true;
toolStripControlHost.Size = Size.Empty;
var toolStripDropDown = new ToolStripDropDown();
toolStripDropDown.Margin = Padding.Empty;
toolStripDropDown.Padding = Padding.Empty;
toolStripDropDown.DropShadowEnabled = false;
toolStripDropDown.AutoSize = true;
toolStripDropDown.Size = Size.Empty;
toolStripDropDown.Items.Add(toolStripControlHost);
toolStripDropDown.Show(this, button1.Location, ToolStripDropDownDirection.AboveRight);
}
}
}
I noticed that the font changes when a control is inserted into toolStripControlHost, so I inserted the following code to try it out and make the font explicit, and it works fine now.
toolStripControlHost.Font = DefaultFont;

Controls not appearing despite being defined

I'm trying to create a Windows Form Control programatically, from scratch without using the WinForms Designer, but for some odd reason, none of the controls seem to be initialized.
When controls are dragged into the designer (and obviously with the InitializeComponent() method uncommented), they appear, but anything done programically outside doesn't appear.
I've went through to debug it and the code runs without any errors, but the label doesn't appear.
Question: Am I missing something?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinForm_Console
{
public partial class Form1 : Form
{
public Form1()
{
// InitializeComponent();
Initialize();
}
Label label1 = new Label();
public void Initialize()
{
this.Text = "WinForm Console Application";
SuspendLayout();
label1.AutoSize = true;
label1.Location = new System.Drawing.Point(129, 112);
label1.Name = "label1";
label1.Size = new System.Drawing.Size(35, 13);
label1.TabIndex = 0;
label1.Text = "label1";
label1.Show();
ResumeLayout(false);
PerformLayout();
}
}
}
Note that some of this code was copied from the designer, after my original attempt failed (which is the same thing without the extra information; initial label, size, logic suspending, etc.)
You have to put the control in the parent control Form. After creating the label, do this.
this.Controls.Add(label1);
Like this,
public void Initialize()
{
this.Text = "WinForm Console Application";
SuspendLayout();
label1.AutoSize = true;
label1.Location = new System.Drawing.Point(129, 112);
label1.Name = "label1";
label1.Size = new System.Drawing.Size(35, 13);
label1.TabIndex = 0;
label1.Text = "label1";
label1.Show();
this.Controls.Add(label1); //very very very important line!
ResumeLayout(false);
PerformLayout();
}

How do I access the text in a text box from a button click event handler

Im trying to write this simple winform menu and I need to add the contents of the NBox text box to a string so I can display it when a button is pressed, however I keep getting the error that NBox does not exist in the current context. So, how would i got about making the contents of the text box available at the press of a button?
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
//namespace game{
class MainM : Form{
public MainM(){
Text = "Adventures Main Menu";
Size = new Size(400,400);
//NameBox
TextBox NBox = new TextBox();
NBox.Location = new Point(145, 100);
NBox.Size = new Size(200, 30);
//Title Label
Label title = new Label();
title.Text = "ADVENTURE THE GAME";
title.Location = new Point(145, 30);
title.Size = new Size(200,60);
title.Font = new Font(defaultFont.FontFamily, defaultFont.Size, FontStyle.Bold);
//The main menu Buttons and all that jazz
Button credits = new Button();
Button start = new Button();
//Credits Button
credits.Text = "Credits";
credits.Size = new Size(75,20);
credits.Location = new Point(145,275);
credits.Click += new EventHandler(this.credits_button_click);
//Start Button
start.Text = "Start";
start.Size = new Size(75,20);
start.Location = new Point(145,200);
start.Click += new EventHandler(this.start_button_click);
//Control addition
this.Controls.Add(title);
this.Controls.Add(credits);
this.Controls.Add(start);
this.Controls.Add(NBox);
}
public void test(){
//The Main Window
}
private void credits_button_click(object sender, EventArgs e){
MessageBox.Show("Created by: Me");
}
private void start_button_click(object sender, EventArgs e){
this.Hide();
string name = NBox.Text;
MessageBox.Show(name);
//Process.Start("TextGame.exe");
}
public static void Main(){
Application.Run(new MainM());
}
}
//}
First, you need to name the control, that name will be its key in container's Controls collection :
//NameBox
TextBox NBox = new TextBox();
NBox.Location = new Point(145, 100);
NBox.Size = new Size(200, 30);
NBox.Name = "NBox"; //Naming the control
Then you will be able to retrieve it from the container:
private void start_button_click(object sender, EventArgs e){
this.Hide();
TextBox NBox= (TextBox)Controls.Find("NBox", true)[0];//Retrieve controls by name
string name = NBox.Text;
MessageBox.Show(name);
//Process.Start("TextGame.exe");
}
You declared NBox in consturctor and it is visible only inside constructor. You need to move it outside of constructor.
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
//namespace game{
class MainM : Form{
TextBox NBox;
public MainM(){
Text = "Adventures Main Menu";
Size = new Size(400,400);
//NameBox
NBox = new TextBox();
...

How can I print a user selected document?

I want to select a file using a file dialog and then print the selected file using the PrintDocument.Print method.
Below is some code which is a partial implementation of what I am trying to accomplish:
using System;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
namespace InstalledAndDefaultPrinters
{
class Program
{
static void Main(string[] args)
{
string filename="";
foreach (string printer in PrinterSettings.InstalledPrinters)
Console.WriteLine(printer);
var printerSettings = new PrinterSettings();
Console.WriteLine(string.Format("The default printer is: {0}", printerSettings.PrinterName));
Console.WriteLine(printerSettings.PrintFileName);
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "Open File Dialog";
fdlg.InitialDirectory = #"C:\ ";
fdlg.RestoreDirectory = true;
fdlg.ShowDialog();
Console.WriteLine(fdlg.Title);
if (fdlg.ShowDialog() == DialogResult.OK)
{
filename = String.Copy(fdlg.FileName);
}
Console.WriteLine(filename);
PrintDialog printdg = new PrintDialog();
PrintDocument pd_doc = new PrintDocument();
printdg.ShowDialog();
if (printdg.ShowDialog() == DialogResult.OK)
{
It is at this point that I would like to print the selected file.
pd_doc.Print();
}
}
The code I have above clearly does not do what I need. What alternative approach might steer me in the right direction?
You can solve that using following code snippet.It works as you want.
private void button1_Click(object sender, EventArgs e)
{
PrintDialog printdg = new PrintDialog();
if (printdg.ShowDialog() == DialogResult.OK)
{
PrintDocument pd = new PrintDocument();
pd.PrinterSettings = printdg.PrinterSettings;
pd.PrintPage += PrintPage;
pd.Print();
pd.Dispose();
}
}
private void PrintPage(object o, PrintPageEventArgs e)
{
System.Drawing.Image img = System.Drawing.Image.FromFile(#"C:\Users\therath\Desktop\372\a.jpg");
// You can replace your logic # here to load the image or whatever you want
Point loc = new Point(100, 100);
e.Graphics.DrawImage(img, loc);
}

Categories

Resources