签名用户控件:智能手机、PocketPCs 和 PDA 上的图形编程






4.67/5 (4投票s)
在本文中,我们将了解图形在智能手机和 PDA 应用程序中的用法。
引言
在本文中,我们将了解图形在智能手机和 PDA 应用程序中的用法。本应用程序的目标是
- 让用户对 C#
Graphics
类有一个基本的了解。 - 创建一个智能手机签名控件,该控件使用 C#
Graphics
类。 - 创建一个使用签名用户控件的 Autograph 应用程序。
使用 C# 进行图形编程
在开始代码讲解之前,我们将从 C# Graphics
类及其方法开始。借助 System.Drawing
命名空间中的 Graphics
类,您可以渲染各种形状。这些形状包括矩形、填充矩形、直线、椭圆、填充椭圆、扇形、填充扇形和多边形。此类定义了绘制这些形状的方法。每种方法根据形状的需求而有所不同。
- 直线、简单形状。
- 来自位图和其他图像文件的图像。
- 文本。
与 C# Windows 应用程序类似,智能手机或 PDA 也使用图形类。在需要生成图表或从用户获取签名的智能手机应用程序中,图形得到了广泛应用。
命名空间 | Contains |
System.Drawing |
大多数与绘图基本功能相关的类、结构、枚举和委托。 |
Graphics 类上的每个方法都必须通过创建 Graphics
类的对象 (g
) 来访问。下表显示了该类的一些方法。
矩形 | DrawRectangle (System.Drawing.Pen, float x, float y, float width, float height) |
g.DrawRectangle (new Pen(Color.Pink,2), 20,20,300,150); |
填充矩形 | 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); |
椭圆 | DrawEllipse(System.Drawing.Pen, float x, float y, float width, float height) |
g.DrawEllipse(new Pen(Color.Pink,3), 15,15,200,150); |
填充椭圆 | 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) |
填充扇形 | 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)}); |
填充多边形 | 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)}); |
使用 Pen
类,您可以指定边框的颜色和粗细。从上面的示例可以看出,Pen
类用于绘制形状,而 Brush
类用于填充形状。我希望您从上表对 Graphics
类及其方法有了一些了解。
Using the Code
创建签名控件 (Signature.dll)
创建一个新的智能设备项目,并将其命名为“SignatureControl”。选择类库作为项目模板。
现在,您将拥有一个名为“Signaturecontrol”的 Visual Studio 项目和一个名为“Class1”的类文件。将类文件重命名为“SignatureControl.cs”。
包含这些命名空间
using System.Windows.Forms; // To inherit control class
using System.Drawing; // To use graphics ,Pen class
using System.IO; // to write the signature to a physical location
并添加这些引用
System.Windows.Forms
System.Drawing
“SignatureControl
”类继承自“Control
”类。它定义了具有可视表示形式的控件的基类。
public partial class SignatureControl : Control
现在,我们将尝试重写绘制签名时触发的事件和方法。
/* *************Developed by Lison Jose P
Software Engineer, Date:23-06-2008 ******************/
#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
//GDI object
Bitmap bmp;
//Graphics object
Graphics graphics;
//Pen object
Pen pen = new Pen(Color.Black);
// Array List of line segments
ArrayList signCoord = new ArrayList();
//Point object
Point lastPoint = new Point(0, 0);
// if drawing signature or not
bool drawSign = false;
#endregion
#region Constructor
public SignatureControl()
{
//Default Constructor
}
#endregion
#region Override Events
#region OnPaint
/// <summary>
/// Create GDI object.Initilize memory bitmap where we draw the
/// signature.
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
// we draw on the memory bitmap on mousemove so there
// is nothing else to draw at this time
CreateGdiObjects();
e.Graphics.DrawImage(bmp, 0, 0);
}
#endregion
#region OnPaintBackground
/// <summary>
/// Override OnPaintBackground to avoid flashing
/// </summary>
/// <param name="e"></param>
protected override void OnPaintBackground(PaintEventArgs e)
{
// don't pass to base since we paint everything, avoid flashing
}
#endregion
#region OnMouseDown
/// <summary>
/// OnMouseDown, get the new X,Y coordinates
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
// process if currently drawing signature
if (!drawSign)
{
// start collecting points
drawSign = true;
// use current mouse click as the first point
lastPoint.X = e.X;
lastPoint.Y = e.Y;
}
}
#endregion
#region OnMouseUp
/// <summary>
/// Set bool drawsign to false
/// </summary>
/// <param name="e"></param>
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
// process if drawing signature
if (drawSign)
{
// stop collecting points
drawSign = false;
}
}
#endregion
#region OnMouseMove
/// <summary>
/// Draw line and get new X,Y coordinates
/// Each drawn coordinates are added in to an arrayList (signCoord )
/// </summary>
/// <param name="e"></param>
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
// process if drawing signature
if (drawSign)
{
if (graphics != null)
{
// draw the new segment on the memory bitmap
graphics.DrawLine(pen, lastPoint.X, lastPoint.Y, e.X,e.Y);
signCoord .Add(lastPoint.X + " " + lastPoint.Y + " " + e.X + " " + e.Y);
// update the current position
lastPoint.X = e.X;
lastPoint.Y = e.Y;
// Invalidates the entire surface of the control and
//causes the control to be redrawn.
Invalidate();
}
}
}
#endregion
#endregion
#region Methods
#region Clear
/// <summary>
/// Clear the signature.
/// </summary>
public void Clear()
{
signCoord .Clear();
InitBitMap();
Invalidate();
}
#endregion
#region CreateGdiObjects
/// <summary>
/// Create an bitMap objects, required to draw signature.
/// </summary>
private void CreateGdiObjects()
{
if (bmp == null || bmp.Width != this.Width || bmp.Height != this.Height)
{
// memory bitmap to draw on
InitBitMap();
}
}
#endregion
#region InitBitMap
/// <summary>
///Initilize the bitmap that is used to draw the signature.
/// </summary>
private void InitBitMap()
{
// load the background image
bmp = new Bitmap(this.Width, this.Height);
graphics = Graphics.FromImage(bmp);
graphics.Clear(Color.SlateGray);
}
#endregion
#region StoreSigData
/// <summary>
/// Get each set of coordinates from the arrayList and concatinate
/// in to a single string.
/// </summary>
/// <param name="fileName">file name
/// (physical position to store the signature coordinates)</param>
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
/// <summary>
/// To create signature file in a physical location. (System.IO)
/// File consist of each co-ordinates of the signature
/// </summary>
/// <param name="fileName">file name</param>
/// <param name="fileContent">file contents (signature
/// coordinates</param>
private void CreateFile(String fileName, String fileContent)
{
StreamWriter sr = File.CreateText(fileName);
sr.WriteLine(fileContent);
sr.Close();
}
#endregion
#region getSignCoord
/// <summary>
/// Get all signature coordinates that are stored in arrayList
/// Return the signature arraylist to the calling form.
/// On the calling Form, this coordinates can be stored in to
/// database.
/// </summary>
/// <returns>arraylist of signature co-ordinates</returns>
public ArrayList getSignCoord ()
{
return signCoord ;
}
#endregion
#region GetSignData
/// <summary>
/// Calling Form take the signature coordinates from file or database
/// and send as string array to this method.
/// This method retrive each coordinates from string array
/// and send
/// </summary>
/// <param name="result">signature co-ordinates</param>
public void GetSignData(string[] result)
{
Graphics graphics;
// load the background image
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
}
}
现在,从项目属性中选择输出类型为 ClassLibrary,然后生成项目。SignatureControl.dll 文件将创建在项目的 bin 文件夹中。
使用签名控件创建 Autograph 应用程序 (Signature.dll)
创建一个新的智能设备项目,并选择设备应用程序模板。将项目命名为“Autograph”。首先,我们为此应用程序创建数据库。向项目添加一个新的 SQL Mobile 数据库 (.SDF)。将其命名为 SignatureDB.sdf。添加一个名为 tblSignature 的表。在该表中包含以下字段:signName
(nvarchar
)、signRegard
(nvarchar
) 和 signSignature
(ntext
)。
现在,为我们的 Autograph 应用程序创建一个类文件。在名为“Component”的文件夹中添加一个新类文件,并将类文件名命名为 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
/// <summary>
/// Method to connect to sql Server
/// </summary>
///<returns>SqlCeConnection</returns>
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
/// <summary>
/// Set the signature deails to database
/// </summary>
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
/// <summary>
/// Get the Signature details from database
/// </summary>
/// <returns>Table of signature details</returns>
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
}
}
数据库类型是 SQL Mobile Database (.SDF),因此请添加此命名空间
using System.Data.SqlServerCe;
现在,向此项目添加两个窗体:一个用于添加签名,另一个用于查看签名。将它们命名为 frmSignature.cs 和 frmViewAll.cs。按照上面的示例截图设计窗体。窗体的代码如下。
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
}
}
在您的移动设备上运行该应用程序。现在,如果有名人或您心爱的人来找您签名,您就不必再去找纸和笔了。只需在您的手机上打开此应用程序即可获得电子签名。它还可以帮助您存储其他详细信息,如电话号码、物品清单等,并且易于检索。