Introduction
In this article we are going to see the use of graphics in Smart Phones and PDA applications. The goals of this application are:
- To allow users have a basic idea of the C#
Graphics
class.
- Create a signature control for a Smart Phone which uses the C#
Graphics
class.
- Create an Autograph application which uses the signature user control.
Graphics Programming Using C#
Before we go to code explanations, we will start with the C# Graphics
class and its methods. With the help of the Graphics
class of the System.Drawing
namespace, you can render various kinds of shapes. These include Rectangle, Filled Rectangle, Lines, Ellipse, Filled Ellipse, Pie, Filled Pie, and Polygons. This class defines methods for painting these shapes. Each method differs according to the needs of the shapes:
- Lines, simple shapes.
- Images from bitmap and other image files.
- Text.
Similar to a C# Windows application, Smart Phones or PDAs also use graphics classes. Graphics are extensively used in Smart Phone applications where there is a requirement for generating graphs or to get signatures from users.
Namespace |
Contains |
System.Drawing |
Most of the classes, structs, enums, and delegates concerned with the basic functionality of drawing. |
Every method on the Graphics class has to be accessed by creating an object (g
) of the Graphics
class. The table below shows some of the methods of this class:
Graphics Class Methods
Rectangle |
DrawRectangle (System.Drawing.Pen, float x, float y, float width, float height) |
g.DrawRectangle (new Pen(Color.Pink,2), 20,20,300,150); |
Filled Rectangle |
FillRectangle(System.Drawing.Brush, float x, float y, float width, float height) |
g.FillRectangle (new SolidBrush(Color.Pink), 15,15,200,60); |
Line |
DrawLine(System.Drawing.Pen, float x, float y, float width, float height) |
g.DrawLine(new Pen(Color.Pink,3), 20,20,300,150); |
Ellipse |
DrawEllipse(System.Drawing.Pen, float x, float y, float width, float height) |
g.DrawEllipse(new Pen(Color.Pink,3), 15,15,200,150); |
Filled Ellipse |
FillEllipse(System.Drawing.Brush, float x, float y, float width, float height) |
g.FillEllipse (new SolidBrush(Color.Pink), 20,20,300,150); |
Pie |
DrawPie(System.Drawing.Pen, float x, float y, float width, float height) |
g.DrawPie(new Pen(Color.Black),120,20,170,160,110,100) |
FilledPie |
FillPie(System.Drawing.Brush, float x, float y, float width, float height) |
g.FillPie(new Brush(Color.Black),120,20,170,160,110,100) |
Polygon |
DrawPolygon(System.Drawing.Pen, new Point[] { new Point(x,y), new Point(x,y), new Point(x,y), new Point(x,y), new Point(x,y), new Point(x,y)}); |
g.DrawPolygon(new Pen(Color.Red,2), new Point[] { new Point(140,170), new Point(155,200), new Point(160,245), new Point(195,230), new Point(30,360), new Point(60,200)}); |
FilledPolygon |
FillPolygon(System.Drawing.Brush, new Point[] { new Point(x,y), new Point(x,y), new Point(x,y), new Point(x,y), new Point(x,y), new Point(x,y)}); |
g.FillPolygon(new Brush(Color.Red), new Point[] { new Point(140,170), new Point(155,200), new Point(160,245), new Point(195,230), new Point(30,360), new Point(60,200)}); |
Using the Pen
class, you can specify the color of the border and also the thickness. From the example given above, it can be seen that the Pen
class is to be applied for drawing shapes while the Brush
class is applied for filling shapes. I hope you got some idea on the Graphics
class and its methods from the above table.
Using the Code
Create Signature Control (Signature.dll)
Create a new Smart Device project and name it “SignatureControl”. Select Class Library as the project template.
Now, you have a Visual Studio project with the name "Signaturecontrol" and a class file named “Class1”. Rename the class file to “SignatureControl.cs”.
Include these namespaces:
using System.Windows.Forms; using System.Drawing; using System.IO;
and add these references:
System.Windows.Forms
System.Drawing
The class “SignatureControl
” inherits from the “Control
” class. It defines the base class for controls, which are components with a visual representation.
public partial class SignatureControl : Control
Now, we will try to override the events and methods that are triggered while a signature is drawn.
#region Namespace
using System;
using System.Collections;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
#endregion
namespace SignatureManipulation
{
public partial class SignatureControl : Control
{
#region Variable declaration
Bitmap bmp;
Graphics graphics;
Pen pen = new Pen(Color.Black);
ArrayList signCoord = new ArrayList();
Point lastPoint = new Point(0, 0);
bool drawSign = false;
#endregion
#region Constructor
public SignatureControl()
{
}
#endregion
#region Override Events
#region OnPaint
protected override void OnPaint(PaintEventArgs e)
{
CreateGdiObjects();
e.Graphics.DrawImage(bmp, 0, 0);
}
#endregion
#region OnPaintBackground
protected override void OnPaintBackground(PaintEventArgs e)
{
}
#endregion
#region OnMouseDown
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (!drawSign)
{
drawSign = true;
lastPoint.X = e.X;
lastPoint.Y = e.Y;
}
}
#endregion
#region OnMouseUp
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (drawSign)
{
drawSign = false;
}
}
#endregion
#region OnMouseMove
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (drawSign)
{
if (graphics != null)
{
graphics.DrawLine(pen, lastPoint.X, lastPoint.Y, e.X,e.Y);
signCoord .Add(lastPoint.X + " " + lastPoint.Y + " " + e.X + " " + e.Y);
lastPoint.X = e.X;
lastPoint.Y = e.Y;
Invalidate();
}
}
}
#endregion
#endregion
#region Methods
#region Clear
public void Clear()
{
signCoord .Clear();
InitBitMap();
Invalidate();
}
#endregion
#region CreateGdiObjects
private void CreateGdiObjects()
{
if (bmp == null || bmp.Width != this.Width || bmp.Height != this.Height)
{
InitBitMap();
}
}
#endregion
#region InitBitMap
private void InitBitMap()
{
bmp = new Bitmap(this.Width, this.Height);
graphics = Graphics.FromImage(bmp);
graphics.Clear(Color.SlateGray);
}
#endregion
#region StoreSigData
public void StoreSigData(String fileName)
{
string sigData = "";
for (int i = 0; i < signCoord .Count; i++)
{
sigData = sigData + signCoord [i].ToString() + "\n";
}
CreateFile(fileName, sigData);
}
#endregion
#region CreateFile
private void CreateFile(String fileName, String fileContent)
{
StreamWriter sr = File.CreateText(fileName);
sr.WriteLine(fileContent);
sr.Close();
}
#endregion
#region getSignCoord
public ArrayList getSignCoord ()
{
return signCoord ;
}
#endregion
#region GetSignData
public void GetSignData(string[] result)
{
Graphics graphics;
bmp = new Bitmap(this.Width, this.Height);
graphics = Graphics.FromImage(bmp);
graphics.Clear(Color.SlateGray);
for (int i = 0; i < result.Length - 2; i++)
{
string[] strArr = new string[4];
strArr = ((result[i].ToString()).Split(' '));
graphics.DrawLine(pen, Convert.ToInt32(strArr[0].ToString()),
Convert.ToInt32(strArr[1].ToString()),
Convert.ToInt32(strArr[2].ToString()),
Convert.ToInt32(strArr[3].ToString()));
Invalidate();
strArr = null;
}
}
#endregion
#endregion
}
}
Now, select the output type as ClassLibrary from the project properties and build the project. The SignatureControl.dll file is created in the project bin folder.
Create Autograph Application Using Signature Control (Signature.dll)
Sample Screen (Autograph .exe)
Create a new Smart Device project and select Device Application template. Name the project as “Autograph”. First, we create the database for this application. Add a new SQL Mobile Database (.SDF) to the project. Name it SignatureDB.sdf. Add a table named tblSignature. Include these fields in the table: signName
(nvarchar
), signRegard
(nvarchar
), and signSignature
(ntext
).
Now, create a class file for our Autograph application. Add a new class file inside a folder named “Component” and name the class file as Signature.cs.
Signature.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlServerCe;
using System.Reflection;
using System.IO;
namespace Autograph.Component
{
class Signature
{
private string _name=string.Empty;
private string _signature=string.Empty;
private string _regards = string.Empty;
public string Name
{
set { _name = value; }
get { return _name; }
}
public string Sign
{
set { _signature = value; }
get { return _signature; }
}
public string Regards
{
set { _regards = value; }
get { return _regards; }
}
#region GetSqlCeConnection
public static SqlCeConnection GetSqlCeConnection()
{
SqlCeConnection cnMindNet = null;
String connString = Assembly.GetExecutingAssembly().GetName().CodeBase;
connString = connString.Replace("Autograph.exe", "SignatureDB.sdf");
cnMindNet = new SqlCeConnection(String.Format("Data Source={0}", connString));
return cnMindNet;
}
#endregion
#region SetSign
public void SetSign()
{
using (SqlCeConnection conn = GetSqlCeConnection())
{
conn.Open();
string query = "insert into tblSignature (signName,signRegards," +
"signSignature) values " +
" ( @name,@regards,@sign )";
SqlCeCommand cmd = new SqlCeCommand(query, conn);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = _name;
cmd.Parameters.Add("@regards", SqlDbType.NVarChar).Value = _regards;
cmd.Parameters.Add("@sign", SqlDbType.NText).Value = _signature;
cmd.ExecuteNonQuery();
}
}
#endregion
#region GetSign
public DataTable GetSign()
{
using (SqlCeConnection conn = GetSqlCeConnection())
{
conn.Open();
DataTable dt = new DataTable();
string query = "select signName,signRegards," +
"signSignature from tblSignature";
SqlCeCommand cmd = new SqlCeCommand(query, conn);
cmd.CommandType = CommandType.Text;
SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);
da.Fill(dt);
return dt;
}
}
#endregion
}
}
The database type is SQL Mobile Database (.SDF), so add this namespace:
using System.Data.SqlServerCe;
Now, add two forms to this project: one to add signature and the other to view the signatures. Name them as frmSignature.cs and frmViewAll.cs. Design the form as in the above sample screenshots. The code for the forms follows.
frmSignature.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
namespace Autograph
{
public partial class frmSignature : Form
{
#region Constructor
public frmSignature()
{
InitializeComponent();
txtName.Focus();
}
#endregion
#region lnklProcess_Click
private void lnklProcess_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
ArrayList arrSign = new ArrayList();
arrSign = uctrlSignature.getPVector();
if (txtName.Text.Trim() == string.Empty)
{
MessageBox.Show(" Name please ", "Autograph",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk,
MessageBoxDefaultButton.Button1);
Cursor.Current = Cursors.Default;
return;
}
if (arrSign.Count > 0)
{
string singature = "";
for (int i = 0; i < arrSign.Count; i++)
{
singature = singature + arrSign[i].ToString() + "*";
}
Component.Signature objSign = new Autograph.Component.Signature();
objSign.Name = txtName.Text;
objSign.Regards = txtNotes.Text;
objSign.Sign = singature;
objSign.SetSign();
MessageBox.Show(" Thank You :) ", "Autograph", MessageBoxButtons.OK,
MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
}
else
{
MessageBox.Show(" Signature please ", "Autograph", MessageBoxButtons.OK,
MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
}
Cursor.Current = Cursors.Default;
}
#endregion
#region lnklClear_Click
private void lnklClear_Click(object sender, EventArgs e)
{
uctrlSignature.Clear();
}
#endregion
#region lnklView_Click
private void lnklView_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
frmViewAll objView = new frmViewAll();
objView.Show();
}
#endregion
#region miAbout_Click
private void miAbout_Click(object sender, EventArgs e)
{
frmAbout objAbout = new frmAbout();
objAbout.Show();
}
#endregion
#region miClose_Click
private void miClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
#endregion
#region frmSignature_Closing
private void frmSignature_Closing(object sender, CancelEventArgs e)
{
Application.Exit();
}
#endregion
}
}
frmViewAll.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Autograph
{
public partial class frmViewAll : Form
{
bool flag = false;
#region Constructor
public frmViewAll()
{
InitializeComponent();
txtLookUp.Focus();
}
#endregion
#region frmViewAll_Load
private void frmViewAll_Load(object sender, EventArgs e)
{
Component.Signature objSign = new Autograph.Component.Signature();
DataTable dtSign = objSign.GetSign();
if (dtSign.Rows.Count > 0)
{
flag = true;
for (int i = 0; i < dtSign.Rows.Count; i++)
{
DataRow dr = dtSign.Rows[i];
ListViewItem item = new ListViewItem(dr["signName"].ToString());
item.SubItems.Add(dr["signRegards"].ToString());
item.SubItems.Add(dr["signSignature"].ToString());
lsvItem.Items.Add(item);
}
}
Cursor.Current = Cursors.Default;
}
#endregion
#region lsvItem_SelectedIndexChanged
private void lsvItem_SelectedIndexChanged(object sender, EventArgs e)
{
if (flag)
{
Cursor.Current = Cursors.WaitCursor;
if (lsvItem.FocusedItem != null)
{
string[] arrStr = (lsvItem.FocusedItem.SubItems[2].Text).Split('*');
uctrlSignature.GetSignData(arrStr);
}
Cursor.Current = Cursors.Default;
}
}
#endregion
#region txtLookUp_TextChanged
private void txtLookUp_TextChanged(object sender, EventArgs e)
{
string strLook = string.Empty;
string check = string.Empty;
string strLookUp = txtLookUp.Text;
int resultRow = 0;
if (strLookUp != "")
{
for (int i = 0; i < lsvItem.Items.Count; i++)
{
strLook = lsvItem.Items[i].SubItems[0].Text.ToLower();
if (strLookUp.Length <= strLook.Length)
{
check = strLook.Substring(0, strLookUp.Length).ToLower();
if (check == strLookUp)
{
resultRow = i;
lsvItem.Items[resultRow].Focused = true;
lsvItem.Items[resultRow].Selected = true;
break;
}
}
}
}
}
#endregion
#region miBack_Click
private void miBack_Click(object sender, EventArgs e)
{
this.Close();
this.Dispose();
}
#endregion
#region miClose_Click
private void miClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
#endregion
#region uctrlSignature_GotFocus
private void uctrlSignature_GotFocus(object sender, EventArgs e)
{
uctrlSignature.Capture = false;
}
#endregion
}
}
Run the application in your mobile device. Now you don’t need to go and search for paper and pen if there comes a celebrity or your loved one to have their “Autograph” with you. Just open this application on your mobile and have it electronically. It also helps you to store other details like, phone number, list of items etc., and it is easy to retrieve as well.