| |
|
|
| |
|
|
| |
| |
|
User Interfaces in VB 2005: a simple calculator:
Some requirements:
Let's do additions only.
Addition requires two numbers; clicking the Add button
when only one number is present or when one or both of the numbers are
not numbers generates an error. The error must pop up in a modal window.
When a new number is entered, the sum/result field must be
cleared.
Note that the interface is a GUI.
Note that the interface is a so-called form.
Note that the interface is displayed in a window --> window (not console) application.
In VB 2005, setup a Windows Application
(not a Console
Application!!) project (File --> New
--> Project --> Windows Application).
Notice how the VB 2005 IDE automatically generates an empty form
for you. Change the file name in the Solution Explorer
from form1.vb into adder.vb.
Partial Class
adder
Inherits System.Windows.Forms.Form
Because of this inheritance, your Form1 class now has all
attributes and behaviors that the VB 2005-provided Form class
has.
See what the adder
class is all about:
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class adder
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Text = "Form1"
End Sub
End Class
Notice how the form has a Text attribute called Form1. Also note that the
NOTE a few lines higher warns not to change this Text attribute in the editor,
but rather to change it in the design
view. The reason for this is that since all of this code got
generated automatically, you as a programmer take a risk making
modifications on your own.
In the design view,
select right-click-->properties
and change the Text
attribute from Form1 to
AddForm. Also
change the (Name)
attribute to AddForm. Now check the results in
both design view and code view.
Remember!! A form’s Name attribute refers to its
class name. The Text attribute only refers to
the default Text
attribute displayed in the form window’s header.
Save your results.
Set the startup form to AddForm, so that the form is displayed upon program startup. (Right-click on the project in the Solution Explorer --> Properties --> Startup Form.)
It is important to note that unlike when programming a console
application, when programming a Windows application, VS 2005 does not
allow you to supply your own Main().
Instead, you must specify the 'startup
form.'
Add some interactivity to the form:

Private Sub CloseButtonClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseButton.Click
Dispose()
End Sub
Note how the above subroutine CloseButtonClick() is
declared to handle a Click
event that occurs on the ClickButton
object (Handles
CloseButton.Click). The only content of the subroutine is to
call the Dispose()
method on the form.
Compile and run and notice how the form stays on the
screen until you click the Close
button. Also notice how when you click the Add button,
it depresses but does not result in an action (no event handler defined
for it yet).
Notice that the textboxes all accept typing. This is
problematic, since the SumBox
should not accept any typing; it should be used for display of results
only.
In design view, set the ReadOnly property of the SumBox to true.
Compile and run to check if this worked.
Let us now add some action to AddButton. Its job is to read the contents of FirstBox and SecondBox, then add them up and display the result in SumBox. We code this by adding another event handler (either write the event handler yourself, or have its skeleton generated for you by double clicking the Add button in design view):
Private Sub AddButtonClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddButton.Click
SumBox.Text = CStr(CShort(FirstBox.Text) + CShort(SecondBox.Text))
End Sub
Note how this subroutine gets called when AddButton
is clicked (Handles
AddButton.Click). All it does is convert the Text
properties in FirstBox
and SecondBox
to shorts, adds them up, converts the result back into a string which
is then displayed in the SumBox.
Compile and run this.
What happens when you type a text rather than a number in
either FirstBox or SecondBox and try to add them
up? What happens when you leave one or both boxes empty?
Apparently, our code in AddButtonClick() is not very
flexible. It assumes that the values entered in FirstBox and SecondBox can be converted
into Shorts.
This causes two problems:
If a value contains a decimal point, the information
following the decimal point is rounded (test this!!).
If a text not representing a number is entered, an
exception is thrown and the program dies.
First deal with exceptions in general. Add a try/catch
block to the AddButtonClick()
function that catches any exception:
Private Sub AddButtonClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddButton.Click
Try
SumBox.Text = CStr(CShort(FirstBox.Text) + CShort(SecondBox.Text))
Catch Ex As Exception
End Try
End Sub
Compile and run entering a text for one of the boxes. Note
how the exception is handled (no message), but now the program provides
no feedback to the user on what the problem is.
Change the program so that the exception not only gets caught, but that a meaningful message is displayed to the user. We can do this using a Message Box:
Private Sub AddButtonClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddButton.Click
Try
SumBox.Text = CStr(CShort(FirstBox.Text) + CShort(SecondBox.Text))
Catch Ex As Exception
MsgBox("Invalid Entry...", MsgBoxStyle.OKOnly, "Input error...")
End Try
End Sub
Almost there. One thing left to do is to make sure we can handle both integers and floating point numbers. To do this convert the FirstBox and LastBox inputs into singles rather than shorts:
Private Sub AddButtonClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddButton.Click
SumBox.Text = CStr(Csng(FirstBox.Text) + CSng(SecondBox.Text))
End Sub
One last thing to do is to make sure that as a user types a new number in one of the text boxes, the SumBox is cleared. This way, the SumBox never contains a faulty sum. This, once again can be accomplished with an event handler. Interestingly, this event handler should be called when a user enters a value into either the FirstBox or the SecondBox. Thus, this event handler can be called from two different events:
Private Sub ClearSumBox(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FirstBox.TextChanged, SecondBox.TextChanged
SumBox.Text = ""
End Sub
Notice how in the above example the ClearSumBox()subroutine gets
called when either FirstBox
or SecondBox receives a
TextChanged event.
Suppose we want the little calculator we just wrote to be
kicked off not as a separate application, but instead, it should be
started from a menu option on a window. The parent window also needs a Close option. This would
require some changes and additions to the existing code.
We must define a new window containing a menu. The menu
needs two options:
Calculator...
Close.
In design view,
select a MenuStrip item
from the ToolBox-->Menus
& Toolbars category and fill out the menu’s name (MainMenu) and its
options
Set the startup form to MenuForm.
Compile and run. Notice how the menu and menu item objects
do their work. However, since we have not coded any event handlers on
the menu items, clicking them has no effect.
Double-clicking on the menu item creates an object of class MyForm containing a skeleton event handler. Add the Dispose() call to its contents.
Private Sub CloseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CalculatorToolStripMenuItem.Click
Dispose()
End Sub
Compile and make sure this works.
A click on the CalculatorItem adds a second skeleton event handler. Fill out its code as follows:
Private Sub CalculatorToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CalculatorToolStripMenuItem.Click
MyForm = New AddForm()
MyForm.ShowDialog()
End Sub
Notice that this will not compile as the compiler complains that MyForm is not declared.
Reason: the AddCalculatorItemClick()
subroutine ‘lives’ on the MenuForm
class, but this class does not yet have an object MyForm of class AddForm declared.
Add the following line at the top of the code for MenuForm:
Private MyForm As
AddForm
Now recompile, run, and... hey presto! Notice how the full functionality of the calculator is maintained within the confines of the MenuForm.
General principles illustrated in these notes:
User interfaces in VB 2005 consist of objects that have other
objects that live on them. For instance, a form object
may have a few button
and textbox
objects living on it.
The VB 2005 IDE provides wizards (design view) that help create
and layout the skeleton code for these objects.
All the objects have properties and behavior.
Objects are connected with mouse-based interaction through
event handlers. These event handlers are subroutines that get
automatically called when the specified mouse event occurs. Other types
of event handlers exist as well.
Objects of specific classes can create objects of
other classes.
Once you have a basic set of classes and event handlers, different user interfaces become mere variations on a theme.