Introduction
This article is intended to demonstrate how to create a touchscreen interface for WinForms, using a numeric keypad as an example.
This is not intended to be an in-depth discussion of UI principles, nor good programming practices. It is solely intended as a starting point
for someone looking to develop a touchscreen application wondering how to get started.
Background
Why reinvent the wheel? For the last few years, I've needed to create various touchscreen interfaces for a warehouse environment.
Recently, people (locally) have been asking how to begin writing for a touchscreen. This is intended to get someone started.
Why use a numeric keypad? Simply because this interface is used the most frequently across the environments we've designed for.
Using the code
There's two parts to the code, the tsNumericKeypad
, which is the actual interface, and the tsNumericKeypadTest
.
- Starting with the NumericKeypad, it's a basic keypad, handling the click events. There are a few tricks, though. When programming for a touchscreen,
I've found that it's best to handle the
MouseUp
events. The reason for this is people frequently miss the button they're intending to hit.
Maybe they have fat fingers like me, or maybe they're just a spaz. Either way, by handling the MouseUp
event instead of the MouseDown
or MouseClick
events, you give the user an opportunity to move their finger. This is especially important when using a bolt-on touchscreen addition,
as this will cause parallax.
- Handling the individual button is nothing special. For the numeric buttons, the pad simply concatenates the digit onto the variable holding
the data (which we creatively named
data
for the sample).
Public Sub NumericMouseUp(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button0.MouseUp, Button1.MouseUp, Button2.MouseUp, _
Button3.MouseUp, Button4.MouseUp, Button5.MouseUp, _
Button6.MouseUp, Button7.MouseUp, Button8.MouseUp, Button9.MouseUp
If sender Is Button0 And vData = "0" Then
Exit Sub
End If
Data += sender.text
End Sub
There's also clear and backspace buttons, which modify the data appropriately.
Private Sub buClear_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles buClear.MouseUp
Data = ""
End Sub
Private Sub buBksp_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles buBksp.MouseUp
If Data.Length = 0 Then
Data = ""
Else
Data = Data.Substring(0, Data.Length - 1)
End If
End Sub
Finally, there's an accept and a cancel button. These return a dialog result to the object which launched the keypad. That way the object knows
if it should accept the data or not.
Private Sub buAccept_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles buAccept.MouseUp
DialogResult = DialogResult.OK
Close()
End Sub
Private Sub buCancel_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles buCancel.MouseUp
DialogResult = DialogResult.Cancel
Close()
End Sub
I've left whitespace in the keypad, specifically because it's almost always the case where I need to add additional controls. In this case, I've added
a negative button and a decimal button which can be switched on and off as needed.
Private vAllowNegatives As Boolean = False
Public Property AllowNegatives As Boolean
Get
Return vAllowNegatives
End Get
Set(ByVal value As Boolean)
vAllowNegatives = value
buNegative.Visible = value
If Data.Substring(0, 1) = "-" And value = False Then
Data = Data.Substring(1, Data.Length - 1)
End If
End Set
End Property
Private vAllowDecimals As Boolean = False
Public Property AllowDecimals As Boolean
Get
Return vAllowDecimals
End Get
Set(ByVal value As Boolean)
vAllowDecimals = value
buDecimal.Visible = value
If Data.Contains(".") And value = False Then
Data = Math.Round(Val(Data), 0).ToString
End If
End Set
End Property
For the object which should launch the keypad, you'll just need the following code. It launches the keypad, then when the keypad returns, it handles
the data, but only if the dialog result is OK.
Dim f As New tsNumericKeypad.tsNumericKeypad
Dim dr As DialogResult = f.ShowDialog
If dr = DialogResult.OK Then
Data = f.Data
End If
Lastly is how to handle the data when it's received by the object. I prefer to always launch an event. By doing so, it lets me handle the changed
data elsewhere in the program by adding a handler, without changing the code already written.
Private vData As String = ""
Public Property Data As String
Get
Return vData
End Get
Set(ByVal value As String)
If value = "" Then
value = "0"
End If
vData = value
RaiseEvent DataChanged(Me, New EventArgs)
End Set
End Property
Public Event DataChanged(ByVal sender As Object, ByVal e As EventArgs)
Points of Interest
Please note that the biggest takeaways from this article are to handle touchscreens as if they were mouse events (preferably MouseUp events),
and use buttons big enough for a person's fingers. It's also a good idea to fire events when it changes data, as it makes adding features much easier later on.
History
- 10/12/11 - First copy of this document.