Griaule Biometrics

Home » Creating an Access Control System using VB.2008 and Fingerprint SDK - Interface II

The Access Management form

This is the form that will manage the junction table UserSystem. Since we don’t want a form where we need to enter the UID and the SID for each relation we want, we need to create a more complex interface.

Design

First of all, add a new form to your project:

  1. Click Project Add Windows form…
  2. Rename it to formAccess;
  3. Create your form as follows (pick each control from toolbox – the properties will be explained later):

 

Toolbox

 

 
Control name
Control type
Properties
(1)
ds
DataSet
DataSetName=AccessControlDataSet
(1)
tam
TableAdapterManager
 
(1)
bs_u
BindingSource
DataSource=ds
DataMember=Users
(1)
ta_s
SystemsTableAdapter
 
(1)
ta_us
UserSystemTableAdapter
 
(1)
ta_u
UsersTableAdapter
 
(2)
cmbUsers
ComboBox
DropDownStyle=DropDownList
DataSource=bs_u
DisplayMember=Name
ValueMember=UID
(3)
lbUnenrolled
ListBox
SelectionMode=MultiSimple
DisplayMember=System
(4)
lbEnrolled
ListBox
SelectionMode=MultiSimple
DisplayMember=System
(5)
cmdEnroll
Button
 
(5)
cmdUnenroll
Button
 
(6)
cmdOK
Button
 
(6)
cmdCancel
Button
 

 

Coding

First of all, we need to define the form behavior and actions. Here they are:

  1. When loaded, the form must read the database into our datasets;
  2. The cmbUsers must show the user names (Name property at Users dataset);
  3. The lbEnrolled displays a selectable list of systems (System property at Systems dataset) the selected user is enrolled to;
  4. The lbUnrenrolled displays a selectable list of systems (from System column at Systems dataset) the selected user is NOT enrolled to;
  5. When the user shown on cmbUsers is changed, the content of lbEnrolled and lbUnenrolled must be updated to match the users info;
  6. When clicked, cmdEnroll enrolls the user to systems selected on lbUnrenrolled, creating a new row on UserSystem dataset;
  7. When clicked, cmdUnenroll dismiss the user from systems selected on lbEnrolled, removing the corresponding row from UserSystem dataset;
  8. When cmdOK is clicked, the changes on UserSystem dataset are updated to database and the form is closed;
  9. When cmdCancel is clicked, the changes on table UserSystem dataset are rejected and the form is closed;
Load

When the form is loaded, we must load the database into our datasets (i). To do so, we use the Fill function on each table adapter: 

ta_us.Fill(ds.UserSystem)        ‘ Populate UserSystem DataSet

ta_s.Fill(ds.Systems)            ‘ Populate Systems DataSet

ta_u.Fill(ds.Users)              ‘ Populate Users DataSet 

Behavior

We form behavior is set on form design by setting the desired properties on each form control. For instance, we want the user names displayed on cmbUsers (ii). It can be done using the following cmbUsers properties:

  • DropDownStyle=DropDownList: set control as a drop-down read-only list;
  • DataSource=bs_u: set “bs_u” as the list containing the items to display;
  • DisplayMember=Name: set “Name” as the bs_u property containing the displaying value;
  • ValueMember=UID: set “UID” as the bs_u property containing the actual value;

To ensure that it works fine, we also need to set the bs_u properties:

  • DataSource=ds: set “ds” as the data source that the connector binds to;
  • DataMember=Users: set “Users” as the ds property containing the list to which the connector currently binds to;

Basically, these properties binds bs_u to Users dataset and cmbUsers uses it as a list containing the elements to be displayed. The main advantages of using a binding source instead of using a local list populated with user names is that we use much less code (no need of using a function to populate the list) and all cmbUsers events are magically bound to Users dataset events. In fact, we set its DropDownStyle property as read-only to avoid any edition in this field, which would also change the bound contents on Users dataset.

Populate

We need to populate lbEnrolled (iii) and lbUnenrolled (iv) with Systems dataset contents. To make it easier, we add the whole row to each control and set their DisplayMember property (during form design) to “System”, ensuring that the row’s System property is shown on control interface. We also want multiple item selection on these boxes. To do so, we set their SelectionMode property to MultiSimple.

The code that populates these boxes is shown below. It gets the UID from the row bound to the current cmbUsers item (the Current property) and processes each row on Systems dataset, adding it to lbEnrolled or lbUnenrolled depending on the existence of an entry on UserSystem dataset: 

Dim u As AccessControlDataSet.UsersRow

Dim s As AccessControlDataSet.SystemsRow

 

lbEnrolled.Items.Clear()                             ‘ Clear all items on lbEnrolled

lbUnenrolled.Items.Clear()                           ‘ Clear all items on lbUnenrolled

 

u = CType(bs_u.Current, DataRowView).Row             ‘ Get current Users row

For Each s In ds.Systems.Rows                        ‘ For each row on Systems:

 

    Dim us As Boolean

    Dim qr As String

 

    qr = “SID = “ & s.SID & “ and UID = “ & u.UID    ‘ - QUERY: matching SID/UID

    us = ds.UserSystem.Select(qr).Length > 0         ‘ - Query UserSystem, true if exists

    If us Then                                       ‘ - True?

        lbEnrolled.Items.Add(s)                      ‘ -- add row to lbEnrolled

    Else                                             ‘ - False?

        lbUnenrolled.Items.Add(s)                    ‘ -- add row to lbUnenrolled

    End If

Next                                                 ‘ Go to next Systems row 

Since there are several form actions that repopulate these controls, we’re creating a subroutine containing this code, called PopulateListBoxes().

Events

There are some events that must be handled by this form. The first one is processing the user changed; we need to repopulate lbUnenrolled and lbEnrolled (v) when it happens. Well, when the item bound to the cmbUsers is changed, the related binding source (bs_u) generates an event called PositionChanged, indicated that the value of its Position property changed. So, it’s enough to call the PopulateListBoxes() subroutine when it happens:

If bs_u.Position >= 0 Then                              ‘ Is position valid?

    PopulateListBoxes()                                 ‘ - repopulate list boxes

End If

The if clause is required because this event is also triggered when Users dataset is populated (form loading above) twice, once during dataset cleaned-up (required before loading database contents) and a second time when the data is finally loaded. Well, during cleaning-up, bs_u.Position is -1 (indicating that dataset is empty) and bs_u.Current is void, causing an error when we read this property to get UID value.

The next event is when cmdEnroll is clicked: the selected used must be enrolled to each selected systems on lbUnenrolled list (vi). Each enrollment is done by creating a new row, populating it with current UID/SID values and adding it to the UserSystem dataset:

Dim u As AccessControlDataSet.UsersRow

Dim s As AccessControlDataSet.SystemsRow

 

u = CType(bs_u.Current, DataRowView).Row             ‘ Get current Users row

For Each s In lbUnenrolled.SelectedItems             ‘ For each selected item on lbUnenrolled:

        

    Dim us As AccessControlDataSet.UserSystemRow

 

    us = ds.UserSystem.NewUserSystemRow()            ‘ Create new UserSystem row

    us.UID = u.UID                                   ‘ Set row’s UID property

    us.SID = s.SID                                   ‘ Set row’s SID property

    ds.UserSystem.AddUserSystemRow(us)               ‘ Add new row to UserSystem

Next

PopulateListBoxes()                                  ‘ Repopulate list boxes

 

The opposite event occurs when cmdUnenroll is clicked (vii): the selected user must be dismissed from selected systems on lbEnrolled list. Each dismiss is done by searching the corresponding row and removing it from UserSystem dataset:

Dim u As AccessControlDataSet.UsersRow

Dim s As AccessControlDataSet.SystemsRow

 

u = CType(bs_u.Current, DataRowView).Row             ‘ Get current Users row

For Each s In lbEnrolled.SelectedItems               ‘ For each selected item on lbEnrolled:

        

    Dim us As AccessControlDataSet.UserSystemRow

    Dim qr As String

 

    qr = “SID = “ & s.SID & “ and UID = “ & u.UID    ‘ - QUERY: matching SID/UID

    us = ds.UserSystem.Select(qr)(0)                 ‘ - Query UserSystem, return matching row

    ds.UserSystem.RemoveUserSystemRow(us)            ‘ - Remove it from UserSystem

Next

PopulateListBoxes()                                  ‘ Repopulate list boxes

 

The last two events are triggered when cmdOK (viii) or cmdCancel (ix) is clicked. In the first case, we need to update the changes on dataset to database and then close the form:

Validate()                                           ‘ Validate form

bs_u.EndEdit()                                       ‘ Apply pending changes

tam.UpdateAll(ds)                                    ‘ Update all datasets

Close()                                              ‘ Close form

 

The Validate() call just generate form validation events, verifying the values on all form controls, bs_u.EndEdit() just applies the pending changes to data source bound to it and tam.UpdateAll(ds) updates all datasets in the form. These calls are default when dealing with datasets and binding sources.

On the other hand, when cmdCancel is clicked, it’s enough to close the form without updating anything. For code clarity, we also reject all dataset changes (this call can be safely removed):

ds.RejectChanges()                                   ‘ Reject all changes to datasets

Close()                                              ‘ Close form

The management form

This is our simplest form and will be used to handle all the others.

Design

First of all, add a new form to your project:

  1. Click Project Add Windows form…
  2. Rename it to formManagement;
  3. Create your form as follows:

Coding

Just add handlers to each button to open the referred form (formFingerprints is defined ahead):

  • Users button is clicked: open formUsers form using ShowDialog() function:

formUsers.ShowDialog()
 

  • Systems button is clicked: same for formSystems
  • Fingerprints button is clicked: same for formFingerprints
  • Access button is clicked: same for formAccess
  • Exit button is clicked: close the form:

formUsers.ShowDialog()
 

The ShowDialog function opens the referred form and waits until the form is closed.