To continue our code, right-click on the project in Solution Explorer and select Add and then Class.... Name the class SigBlock.
The SigBlock object starts out with a VB.NET elements we haven't seen before - structures:
Public Class SigBlock
Private m_SigBlock As New SigBlockStruct
Private Structure SigBlockStruct
Dim FName As String
Dim LName As String
Dim Address As String
Dim Phone As String
Dim SSN As String
Dim Email As String
End Structure
We're using this structure as a way of grouping other data types under a single name. The first statement creates a new instance of the structure. When we use the elements in the structure, we'll have to qualify them with the name of this new instance. As we did in part 5, the member variables are initialized in the New subroutine (the "constructor" that is executed automatically when a new instance of the object is created). Here's our New subroutine:
Public Sub New()
m_SigBlock.FName = "Dan"
SigFieldDisplay.FName.Checked = True
m_SigBlock.LName = "Mabbutt"
SigFieldDisplay.LName.Checked = True
m_SigBlock.Address = "About Visual Basic"
SigFieldDisplay.Address.Checked = True
m_SigBlock.Phone = "(555) 555-5555"
SigFieldDisplay.Phone.Checked = False
m_SigBlock.SSN = "123-45-6789"
SigFieldDisplay.SSN.Checked = False
m_SigBlock.Email = "visualbasic@about.com"
SigFieldDisplay.Email.Checked = True
End Sub
The New subroutine also includes statements like this:
SigFieldDisplay.FName.Checked = True
This is our first clue that something is wrong with our design. The OOP principle of encapsulation states that the object should be completely self contained, yet this statement references a component somewhere else in the program. (Actually, it's in a different form that hasn't been discussed yet.) I could have created properties for all of these variables and referenced them in the main form, but since this program has other problems that stem from a similar source, I decided to keep the program shorter and point this out as a problem that will be solved in a later revision.
Initializing variables in the New constructor to provide default values will work as long as we're only managing the information for one person. As soon as it has to manage two or more, we'll need to use a datastore such as a file. And there's another serious design flaw that will have to wait until we start using a file. Although we can change what is displayed, we can't save any of our changes!
Lines is a Property in the SigBlock object. It looks like this:
ReadOnly Property Lines() As String
Get
Lines = vbCrLf
If SigFieldDisplay.FName.Checked Then
Lines &= m_SigBlock.FName & " "
End If
If SigFieldDisplay.LName.Checked Then
< ... and so forth ... >
End Get
End Property
Intrinsic Constants
The Lines Property is accessed just like other properties (for instance, the Text property of a Button or TextBox):
SigBlockBox.Text = mySigBlock.Lines
To create the Lines Property in the Get block, I start out by assigning vbCrLf to the Property. This is an example of an intrinsic constant. These are values that are often hard to remember but are often used in program statements. VB.NET makes life a little easier on you by giving them a name you can remember and then making them a built-in part of the language. In this case, vbCrLf is actually equal to a string combining two unprintable characters - Chr(13) + Chr(10) or "Carriage Return and Line Feed". This value gives you a new line in a display. You can read up on them by searching Microsoft's MSDN site for "Intrinsic Constants and Enumerations".
I add a new value to the end of the string by using the &= short circuit operator. This is just a syntax trick that C programmers have used for a long time. The only real value is to save a few keystrokes. The statement in the program is equivalent to:
Lines = Lines & m_SigBlock.FName & " "
Again, the encapsulation principle isn't followed (If SigFieldDisplay.FName.Checked), but again, it makes an imperfect program a little shorter for the time being. Note that since the Checked property is a Boolean value, we can test it directly instead of coding, "If SigFieldDisplay.FName.Checked = True".
To change the values that are displayed in the signature block, a new form is displayed with
SigFieldDisplay.Show()
Since these are the values that are tested in the SigBlock object, we don't have to do anything else.
SigFieldDisplay is a secondary form. Add it by right-clicking the project in a way similar to the way we created a class earlier. It's simply a form with six checkboxes and a button. The button hides the form again. This makes the form, in effect, a temporary datastore to save our display selections ... at least until the program ends. You can see the code for this secondary form in the download.
The system works ... well ... good enough for a first draft. Download it here.
In the next part of the tutorial, Using Data and Serializing to Files, we make it work a lot better.

