Drawing in Windows Forms C#

Introduction

The Image Drawing Tool software application was developed to design your own Images with , add text, line, and picture. The Image Drawing Tool can be printed to any selected printer. The final design can be saved as XML format for reuse which can also be loaded from the saved XML file. This simple C# application allows the user to:

  1. Add text to design.
  2. Add picture to design.
  3. Create new design.
  4. Save your drawing design as XML file for reuse.
  5. Load from XML file.
  6. Cut, copy, and paste all controls.
  7. Print design to selected printer.
  8. Delete selected controls.
  9. Options to set controls as front or back of other controls.
  10. Resize controls.
  11. Move controls.
Background

The main aim was to develop a simple and easy to use .NET application for Image Drawing. This application was developed using .NET 4.0 (C#) and uses XML and GDI+ functionality.Hope this Application will be as a key for a users to make a standard painting Tool.

Using the Code

Our design is simple - all controls will be added to a Panel control at runtime. I have a main Panel in a form; when a label text is clicked, a new label will be added to the panel at runtime, same as that used for other controls like picture box.

Controls Adding at Runtime
  
The below code explains how to add a designer control at runtime to a Panel. Here for example, I have added code to add a Label control at runtime to a Panel from the menu label click event.
  1. private void toolStripButton1_Click(object sender, EventArgs e)  
  2. {  
  3.     Label ctrl = new Label();  
  4.     ctrl.Location = new Point(50, 50);  
  5.     ctrl.Font = new System.Drawing.Font("NativePrinterFontA", 10F,   
  6.     System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));  
  7.     ctrl.Text = "Shanu";  
  8.     ctrl.MouseEnter += new EventHandler(control_MouseEnter);  
  9.     ctrl.MouseLeave += new EventHandler(control_MouseLeave);  
  10.     ctrl.MouseDown += new MouseEventHandler(control_MouseDown);  
  11.     ctrl.MouseMove += new MouseEventHandler(control_MouseMove);  
  12.     ctrl.MouseUp += new MouseEventHandler(control_MouseUp);  
  13.     pnControls.Controls.Add(ctrl);  
  14. }  
Same as this, all other controls can be added from a menu click event. All controls have MouseEnter, MouseMove, MouseDown, MouseLeave, and MouseUp events for controls to be resized and moved inside aPanelat runtime.
 
Save Drawing as XML File
 
The below function SavetoXML() saves all the control types and properties placed in the panel to an XML file. Here, we get all the controls and properties like font, backcolor, image, and location, and save all information to an XML file in the selected path. To save the Picturebox image, we find the PictureBox controls and convert the PictureBox image into bytes and save the image byte value to the XML file.
  1. private void SavetoXML()  
  2. {  
  3.     XmlDocument xmlDoc = new XmlDocument();  
  4.   
  5.     // Write down the XML declaration  
  6.     XmlDeclaration xmlDeclaration =   
  7.         xmlDoc.CreateXmlDeclaration("1.0""utf-8"null);  
  8.   
  9.     // Create the root element  
  10.     XmlElement rootNode = xmlDoc.CreateElement("ShanuDrawingToolsList");  
  11.     xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);  
  12.     xmlDoc.AppendChild(rootNode);  
  13.   
  14.     foreach (Control p in pnControls.Controls)  
  15.     {  
  16.         string s = p.Name;  
  17.         string types = p.GetType().ToString();  
  18.         string locX = p.Location.X.ToString();  
  19.         string locY = p.Location.Y.ToString();  
  20.         string sizeWidth = p.Width.ToString();  
  21.         string sizeHegiht = p.Height.ToString();  
  22.         string Texts = p.Text.ToString();  
  23.   
  24.         PictureBox pic = p as PictureBox; //cast control into PictureBox  
  25.         byte[] bytes = null;  
  26.         string PicBitMapImages = "";  
  27.         if (pic != null//if it is pictureBox, then it will not be null.  
  28.         {  
  29.             if (pic.Image != null)  
  30.             {  
  31.                 Bitmap img = new Bitmap(pic.Image);  
  32.                 bytes = imageToByteArray(img);  
  33.                 PicBitMapImages = Convert.ToBase64String(bytes);  
  34.             }  
  35.         }  
  36.   
  37.         //Font f = p.Font;  
  38.         string fonts = FontToString(p.Font);  
  39.   
  40.         // Create a new <category> element and add it to the root node  
  41.         XmlElement parentNode = xmlDoc.CreateElement("Controls");  
  42.   
  43.         // Set attribute name and value!  
  44.         parentNode.SetAttribute("ID", p.GetType().ToString());  
  45.   
  46.         xmlDoc.DocumentElement.PrependChild(parentNode);  
  47.   
  48.         // Create the required nodes  
  49.         XmlElement CntrlType = xmlDoc.CreateElement("ControlsType");  
  50.         XmlElement locNodeX = xmlDoc.CreateElement("LocationX");  
  51.         XmlElement locNodeY = xmlDoc.CreateElement("LocationY");  
  52.         XmlElement SizeWidth = xmlDoc.CreateElement("SizeWidth");  
  53.         XmlElement SizeHegith = xmlDoc.CreateElement("SizeHeight");  
  54.         XmlElement cntText = xmlDoc.CreateElement("Text");  
  55.         XmlElement cntFonts = xmlDoc.CreateElement("Fonts");  
  56.         XmlElement CntrlPictureImage = xmlDoc.CreateElement("picImage");  
  57.   
  58.         // retrieve the text   
  59.         XmlText cntrlKind = xmlDoc.CreateTextNode(p.GetType().ToString());  
  60.   
  61.         XmlText cntrlLocX = xmlDoc.CreateTextNode(locX);  
  62.         XmlText cntrlLocY = xmlDoc.CreateTextNode(locY);  
  63.   
  64.         XmlText cntrlWidth = xmlDoc.CreateTextNode(sizeWidth);  
  65.         XmlText cntrlHeight = xmlDoc.CreateTextNode(sizeHegiht);  
  66.   
  67.         XmlText cntrlText = xmlDoc.CreateTextNode(Texts);  
  68.         XmlText cntrlFont = xmlDoc.CreateTextNode(fonts);  
  69.         XmlText cntrlPicImg = xmlDoc.CreateTextNode(PicBitMapImages);  
  70.   
  71.         // append the nodes to the parentNode without the value  
  72.         parentNode.AppendChild(CntrlType);  
  73.         parentNode.AppendChild(locNodeX);  
  74.         parentNode.AppendChild(locNodeY);  
  75.         parentNode.AppendChild(SizeWidth);  
  76.         parentNode.AppendChild(SizeHegith);  
  77.         parentNode.AppendChild(cntText);  
  78.         parentNode.AppendChild(cntFonts);  
  79.         parentNode.AppendChild(CntrlPictureImage);  
  80.         // save the value of the fields into the nodes  
  81.         CntrlType.AppendChild(cntrlKind);  
  82.         locNodeX.AppendChild(cntrlLocX);  
  83.         locNodeY.AppendChild(cntrlLocY);  
  84.   
  85.         SizeWidth.AppendChild(cntrlWidth);  
  86.         SizeHegith.AppendChild(cntrlHeight);  
  87.   
  88.         cntText.AppendChild(cntrlText);  
  89.         cntFonts.AppendChild(cntrlFont);  
  90.         CntrlPictureImage.AppendChild(cntrlPicImg);  
  91.     }  
  92.   
  93.     SaveFileDialog dlg = new SaveFileDialog();  
  94.     dlg.Filter = "XML Files (*.xml)|*.xml";  
  95.   
  96.     if (dlg.ShowDialog() == DialogResult.OK)  
  97.     {  
  98.         xmlDoc.Save(dlg.FileName);  
  99.     }  
  100. }   
Print the Drawing to Selected Printer
 
By clicking on the Print button, the user can select the printer for printing and can preview the design and print the document. To do this, we need to print only the controls inside the main panel. Declare the Printdocument and create an event for print page to select the controls in the panel for printing.
  1. System.Drawing.Printing.PrintDocument doc = new System.Drawing.Printing.PrintDocument();  
  2. doc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(doc_PrintPage);  
  3. //doc.Print();  
  4.   
  5. printDialog1.Document = doc;  
  6.   
  7. // printDialog1.AllowPrintToFile = true;  
  8. printDialog1.AllowSelection = true;  
  9. printDialog1.AllowSomePages = true;  
  10. // printDialog1.PrintToFile = true;  
  11. if (printDialog1.ShowDialog() == DialogResult.OK)  
  12. {  
  13.     // printDocument1.Print();  
  14.   
  15.     previewdlg.Document = doc;  
  16.     previewdlg.ShowDialog();  
  17. }  
In PrintDocument doc_PrintPage, draw the panel as image for printing.
  1. private void doc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)  
  2. {  
  3.     Panel grd =pnControls;  
  4.     Bitmap bmp = new Bitmap(grd.Width, grd.Height, grd.CreateGraphics());  
  5.     grd.DrawToBitmap(bmp, new Rectangle(0, 0, grd.Width, grd.Height));  
  6.     RectangleF bounds = e.PageSettings.PrintableArea;  
  7.     float factor = ((float)bmp.Height / (float)bmp.Width);  
  8.     //e.Graphics.DrawImage(bmp, bounds.Left, bounds.Top, bounds.Width, factor * bounds.Width);  
  9.     e.Graphics.DrawImage(bmp, bounds.Left, bounds.Top, grd.Width, grd.Height);  
  10. }   

For more code details, please refer to the attached ShanuDrawingTool project zip file.

Points of Interest

It was a lot of fun developing this project; this has features like working with GDI+, saving controls and images as XML, control cut, copy, and paste at runtime, etc.

History
  • Updated ShanuDrawingTool.zip - 2014/07/02