65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (4投票s)

2008年7月2日

CPOL

5分钟阅读

viewsIcon

41003

downloadIcon

690

在本文中,我们将了解图形在智能手机和 PDA 应用程序中的用法。

引言

在本文中,我们将了解图形在智能手机和 PDA 应用程序中的用法。本应用程序的目标是

  1. 让用户对 C# Graphics 类有一个基本的了解。
  2. 创建一个智能手机签名控件,该控件使用 C# Graphics 类。
  3. 创建一个使用签名用户控件的 Autograph 应用程序。

使用 C# 进行图形编程

在开始代码讲解之前,我们将从 C# Graphics 类及其方法开始。借助 System.Drawing 命名空间中的 Graphics 类,您可以渲染各种形状。这些形状包括矩形、填充矩形、直线、椭圆、填充椭圆、扇形、填充扇形和多边形。此类定义了绘制这些形状的方法。每种方法根据形状的需求而有所不同。

  • 直线、简单形状。
  • 来自位图和其他图像文件的图像。
  • 文本。

与 C# Windows 应用程序类似,智能手机或 PDA 也使用图形类。在需要生成图表或从用户获取签名的智能手机应用程序中,图形得到了广泛应用。

命名空间 Contains
System.Drawing 大多数与绘图基本功能相关的类、结构、枚举和委托。

Graphics 类上的每个方法都必须通过创建 Graphics 类的对象 (g) 来访问。下表显示了该类的一些方法。

Graphics 类方法
矩形 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 .exe)

创建一个新的智能设备项目,并选择设备应用程序模板。将项目命名为“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.csfrmViewAll.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
    }
}

在您的移动设备上运行该应用程序。现在,如果有名人或您心爱的人来找您签名,您就不必再去找纸和笔了。只需在您的手机上打开此应用程序即可获得电子签名。它还可以帮助您存储其他详细信息,如电话号码、物品清单等,并且易于检索。

© . All rights reserved.