In WPF there’s an interesting control called “InkCanvas” that can be used to capture signatures and the like in Tablet PC applications.
Recently I created a prototype for a windows forms application. I did consider using WPF, but the overhead seemed unnecessary considering the simplicity of the requirement.
I am aware there’s a specific SDK for Tablet PC that provides winforms controls for the requirement, but I thought it might be fun to create my own. As it turns out, it was pretty easy.
The requirement was to have a signature panel which could be used to collect a bitmap that would be attached to an entity to act as an authorisation.
In the prototype I decided to create the signature panel as a standalone usercontrol called it, strangely enough “SignaturePanel”.
It uses Mousedown and MouseUp events to determine stylus pressure and mousemove for drawing. Like the WPF control it keeps a collection of strokes internally.
Unlike the wpf control, I just decided to expose a “SignatureImage” property to allow a developer to retrieve a bitmap. This is rendered from the strokes in realtime.
I assume it works for the Tablet PC, but I don’t know for sure.
Write your signature here
An additional feature of this control is a label which tells the user the last time the signature was last updated. I thought the user may find this helpful.
If the user hasn’t written anything then it just reads “Write your signature here”.
The user control consists of a picturebox called “inkPanel” and a button for resetting the content:
Here’s the code:
Public Class SignaturePanel
Private moCurrentWriting As New List(Of Point)
Private moRememberInk As New List(Of List(Of Point))
Private mbPenDown As Boolean = False
Private Sub inkPanel_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles inkPanel.MouseDown
mbPenDown = True
Private Sub inkPanel_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles inkPanel.MouseMove
If mbPenDown Then
mdLastSignatureUpdate = Now
Private Sub inkPanel_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles inkPanel.MouseUp
If moCurrentWriting.Count > 2 Then
moCurrentWriting = New List(Of Point)
mbPenDown = False
Private Sub inkPanel_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles inkPanel.Paint
Dim lsText As String = ""
If Not Me.DesignMode Then
If mdLastSignatureUpdate.HasValue Then
lsText = "Signature last updated " & Me.LastSignatureUpdate.ToLongTimeString
e.Graphics.DrawString(lsText, Me.Font, Brushes.Black, 5, inkPanel.Height - 20)
lsText = "... Write your signature here ..."
e.Graphics.DrawString(lsText, Me.Font, Brushes.Black, (inkPanel.Width / 2) - (e.Graphics.MeasureString(lsText, Me.Font).Width / 2), (inkPanel.Height / 2) - (e.Graphics.MeasureString(lsText, Me.Font).Height / 2))
Private Sub mRenderSignature(ByVal g As Graphics)
Using loPen As New Pen(Color.Black)
loPen.Width = 2
For Each loLines As List(Of Point) In moRememberInk
If moCurrentWriting.Count > 1 Then
Private Sub cmdClearInk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClearInk.Click
Private mdLastSignatureUpdate As Nullable(Of Date) = Nothing
Public Property LastSignatureUpdate() As Date
Set(ByVal value As Date)
mdLastSignatureUpdate = value
Public ReadOnly Property SignatureImage() As Image
Dim loBitmap As New Bitmap(Me.Width, Me.Height)
Using loGfx As Graphics = Graphics.FromImage(loBitmap)
If anyone’s interested in a standalone sample project, post the request to this blog and I’ll see what I can do.
It may be interesting to use this code as:
- Signature recognition
- “Mud map” style sketching for business applications
- A basis for a drawing program 😉
Of course, if you’re using WPF, use InkPanel. But if you don’t want the overhead, maybe this will be the foundation of a lightweight solution.