Contacts Sub-system

Everything is set up and now we can start on the first sub-system we are going to build – Contacts.

The reason I call this a sub-system is that it really stands on its own. All it does is list all the contacts I have and allow me to add new contacts, edit the details of existing contacts and delete contacts. It will interact with the other sub-systems, but it stands on its own.

If I was building this for a client I could deliver this subsystem prior to building anything else. And if the client decided that they didn’t want the rest of the application then all it would mean is some quick changes to the Main Form and they would have a complete system.

Most of the procedures I use here will be followed in subsequent sub-systems and forms, so I will go into detail for this section, but later on we will move much more quickly.

First thing to do is create a new inherited form called ContactsForm. It is inherited from the BaseForm, as most, if not all, our forms will be. We then hook it up to the menu item on the Main Form called mnuContactDetails. The code looks like this:

Private Sub mnuContactDetails_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles mnuContactDetails.Click
        Dim frm As New ContactForm
        frm.ShowDialog(Me)
End Sub

Notice that, because every form is created from the form class it must be instantiated before it can be used, just like any other object. This is quite different from previous versions of Visual Basic.

Back to our Contact Form, and we will put some controls on it. I want to show a listview which will list all the contacts together with phone number. I will also show all the other details for the contact in text boxes to the right of the listview. There is some disagreement between developers as to whether we should use text boxes or labels for read-only information. In reality, it doesn’t really matter. I use text boxes for information that is coming from the database, and use labels to label things, like other controls. If you are goint to use a text box, as I do, then you need to set the Read-only property to True, otherwise the user will think that they can change the values. I also set the TabStop property to false and the BorderStyle to None. If, as I do, you have used a different background colour for the form than the default control colour, then you also need to set the background colour of the text boxes to the same colour. These properties can all be set at once in a matter of seconds, or you could, if you wished, sub-class the text-box to look just like you want and use the new inherited control. This is probably a more object oriented way of doing it.

Now for a bit on the code. Whenever I fill a list type control, such as a Listview or Treeview, or even a list box or combo box, I always do a couple of things.

  • Set the cursor to wait, that is it will show an hourglass, or whatever equivalent cursor the user has set up as their wait cursor.
  • Prevent the control from updating itself until all the items have been placed into the control. This speeds up the filling of the control.
  • Clear the control
  • Populate the control.
  • Update the control
  • Reset the cursor.

So the code looks like this. My Listview control is named lvContact.

   Cursor.current = Cursors.WaitCursor
   lvContact.BeginUpdate()
   lvContact.Items.Clear()
   '////////////////////////////////////////////////////////////
   'Code for populating the listview goes here
   '///////////////////////////////////////////////////////////
   lvContact.EndUpdate()
   Cursor.Current = Cursors.Default

Populating the listview can be done in a number of ways. First we need to remember that the Listview control is not data aware, so it cannot be databound. You can create a User Control that is data aware, but it is not really necessary. I use an Object-Relational mapper called LLBLGen to create my data layer. There are other O/R mappers around, or you can do it another way. I wouldn’t recommend using datasets, a lot of overhead for no advantage. LLBLGen allows me to create read-only lists which can be sorted, and are returned as data rows. So I add a sort expression and create the list.

So my code for populating the list view is the following:

   Dim myrow as Datarow
   Dim LVI as ListViewItem
   For Each myrow in Contacts 'Contacts is the name of my list
      LVI = lvContact.Items.Add(Cint(myrow(0)))
      LVI.SubItems.Add(Cstr(myrow(1)))
      LVI.SubItems.Add(Cstr(myrow(2)))
   Next

The Contacts List, which I created in LLBLGen, has three fields, ContactID, Name and Phone, and I created them in that order, so they are the fields returned by the datarow. I could have used name fields, rather than refer to them by their index, but this way provides a littel better performance.

There are just couple of things left to do. First, when a contact is selected in the ListView we want to show their details in the Read-only text boxes on the right of the form. So I have declared a Private variable m_contact as a ContactEntity. That is the name which LLBLGen has given to Entity created from my Contact table in the database. When I select a contact I create a new ContactEntity object

m_Contact = New ContactEntity(Cint(lvContact.SelectedItems(0).Text))

I then use the properties of the m_Contact object to populate the text boxes.

Finally, I need to hook up the buttons. The Close button is easy, I just close the form with a Me.Close() method. The other two buttons required the creation of a new form, which is the subject of the next episode.

This has been a long article. We won’t go into as much detail with most of the other forms.

Contact Form