C# PrintPage function from another class - c#

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();
}
}
}
}
}
}

Related

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;

How to display a popup on mouse hover of an HTML element in the WebBrowser control of a Form application

In the following code, C# and js are linked together and ToolStripDropDown is used to create a popup, but the mouseleave event of js does not fire when the mouse leaves the HTML element.
However, when I move the mouse over the popup, the mouseleave event fires.
If you move the mouse away from other directions, the mouseleave event will not fire.
Also, it seems to fire when the popup is not shown on the C# side.
I tried writing a code to focus on the WebBrowser control after Show, but even so, mouseleave of js doesn't fire.
I wonder why this is.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp5
{
public partial class Form1 : Form
{
public ToolStripDropDown toolStripDropDown;
public Form1()
{
InitializeComponent();
toolStripDropDown = new ToolStripDropDown();
toolStripDropDown.Margin = Padding.Empty;
toolStripDropDown.Padding = Padding.Empty;
toolStripDropDown.DropShadowEnabled = false;
webBrowser1.ObjectForScripting = new TestClasss(this);
webBrowser1.DocumentText = #"<script>
window.onload = function() {
var elm = document.createElement('div');
elm.innerHTML = 'test';
document.body.appendChild(elm);
elm.onmouseover = function() {
window.external.ShowPopup(this.getBoundingClientRect().left, this.getBoundingClientRect().top);
};
elm.onmouseleave = function()
{
window.external.ClosePopup();
};
};
</script>";
}
}
[ComVisible(true)]
public class TestClasss
{
private Form1 viewer;
public TestClasss(Form1 viewer)
{
this.viewer = viewer;
}
public void ShowPopup(int x, int y)
{
var panel1 = new Panel();
panel1.BackColor = Color.Red;
var label1 = new Label();
label1.Text = "popup";
panel1.Controls.Add(label1);
var toolStripControlHost = new ToolStripControlHost(panel1);
toolStripControlHost.Margin = Padding.Empty;
toolStripControlHost.Padding = Padding.Empty;
viewer.toolStripDropDown.Items.Clear();
viewer.toolStripDropDown.Items.Add(toolStripControlHost);
viewer.toolStripDropDown.Show(viewer.webBrowser1, new Point(x, y), ToolStripDropDownDirection.AboveRight);
}
public void ClosePopup()
{
viewer.toolStripDropDown.Close();
}
}
}
Try this code
Using System;
Using System.Collections.Generic;
Using System.ComponentModel;
Using System.Data;
Using System.Drawing;
Using System.Text;
Using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form5 : Form
{
public Form5()
{
InitializeComponent();
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
}
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser1.Document.Body.MouseOver += new HtmlElementEventHandler(Body_MouseOver);
}
void Body_MouseOver(object sender, HtmlElementEventArgs e)
{
if (e.ToElement != null && e.ToElement.TagName == "H1" && e.ToElement.GetAttribute("processed") != "true")
{
string[] words = e.ToElement.InnerHtml.Split(' ');
e.ToElement.InnerHtml = "";
for (int i = 0; i < words.Length; i++)
e.ToElement.InnerHtml += "<span> " + words[i] + " </span>";
foreach (HtmlElement el in e.ToElement.GetElementsByTagName("span"))
el.MouseOver += new HtmlElementEventHandler(e_MouseOver);
e.ToElement.SetAttribute("processed", "true");
}
}
void e_MouseOver(object sender, HtmlElementEventArgs e)
{
toolStripTextBox1.Text = e.ToElement.InnerText;
}
}

How to call Input Dialog (Gorkem Gencay) from other class

how can i use 'Gorkem Gencay' InputDialog calling it from another Class?
Edit: Inserted all the code
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 InputDialog
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static DialogResult ShowInputDialog(ref string input)
{
System.Drawing.Size size = new System.Drawing.Size(200, 70);
Form inputBox = new Form();
inputBox.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
inputBox.ClientSize = size;
inputBox.Text = "Name";
System.Windows.Forms.TextBox textBox = new TextBox();
textBox.Size = new System.Drawing.Size(size.Width - 10, 23);
textBox.Location = new System.Drawing.Point(5, 5);
textBox.Text = input;
inputBox.StartPosition = FormStartPosition.CenterParent;
inputBox.Controls.Add(textBox);
Button okButton = new Button();
okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
okButton.Name = "okButton";
okButton.Size = new System.Drawing.Size(75, 23);
okButton.Text = "&OK";
okButton.Location = new System.Drawing.Point(size.Width - 80 - 80, 39);
inputBox.Controls.Add(okButton);
Button cancelButton = new Button();
cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
cancelButton.Name = "cancelButton";
cancelButton.Size = new System.Drawing.Size(75, 23);
cancelButton.Text = "&Cancel";
cancelButton.Location = new System.Drawing.Point(size.Width - 80, 39);
inputBox.Controls.Add(cancelButton);
inputBox.AcceptButton = okButton;
inputBox.CancelButton = cancelButton;
DialogResult result = inputBox.ShowDialog();
input = textBox.Text;
return result;
}
private void Form1_Load(object sender, EventArgs e)
{
string input = "hede";
ShowInputDialog(ref input);
}
}
}
I'm trying the following istead of using the private void Form1_Load(object sender, EventArgs e), but don't work:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace InputDialog
{
class Class1
{
Form1 frm = new Form1();
string input = "hede";
frm.ShowInputDialog(ref input);
}
}
That ShowInputDialog method is defined as static so you need to use class name and not an object name when calling it. Assuming ShowInputDialog is defined in the Form1 class, you should invoke it as follows:
string input = "hede";
Form1.ShowInputDialog(ref input);
By the way, that method is defined as private so you have to make it public or internal.
The Class1 definition also has an error. You can't call procedural code (frm.ShowInputDialog(ref input);) out of procedural context. Define a method and put your dialog invocation code it this method:
class Class1
{
public static void TestDialogCall()
{
string input = "hede";
Form1.ShowInputDialog(ref input);
}
}

Printing Forms using PrintDocument

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();
}

Subsequent displays of custom Tooltip has ugly black edging around border

I created a simple Tooltip class which I'd like to enhance with more features but with just a basic Tooltip I'm running into an issue of it getting an ugly edging along the border when it appears on the second time or thereafter. The first time it displays, it appears correct.
Can anyone tell me why this is happening?
using System;
using System.Data;
using System.Linq;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Drawing.Drawing2D;
using System.Collections.Generic;
class CToolTip : ToolTip
{
public CToolTip()
{
this.OwnerDraw = true;
this.Popup += new PopupEventHandler(this.OnPopup);
this.Draw += new DrawToolTipEventHandler(this.OnDraw);
}
private void OnPopup(object sender, PopupEventArgs e)
{
e.ToolTipSize = new Size(200, 200);
}
private void OnDraw(object sender, DrawToolTipEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.FillRectangle(Brushes.LightYellow, new Rectangle(0, 0, 200, 200));
}
}
I added the CToolTip and a button to a form. Added an event handler for the hover event and display it on a button hover.
this.button1.MouseHover += new System.EventHandler(this.button1_MouseHover);
private void button1_MouseHover(object sender, EventArgs e)
{
cTip.SetToolTip(button1, "This is a test");
}
It ended up being this line. When I removed it, the problem went away.
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

Categories

Resources