![]() | |
|
|
|
To access the contents, click the chapter and section titles.
Advanced Visual Basic Techniques
AppointmentBook stores the objects and their event masks in the Views and Events collections. Adding a new view to the list with RegisterView is simple.
Private Views As New Collection
Private Events As New Collection
:
Public Sub RegisterView(view As Object, event_mask As Long)
Views.Add view
Events.Add event_mask
End Sub
When an event occurs, the model must notify the interested views. The NotifyViews subroutine described in the earlier section, Bit Masks in AppointmentBook, does this. It takes as a parameter a mask indicating which event or events just took place. For each view interested in the events, Notify-Views invokes the objects Notify subroutine.
Private Sub NotifyViews(event_mask As Long)
Dim i As Integer
For i = 1 To Views.Count
Notify this view if necessary.
If event_mask And Events.Item(i) Then _
Views.Item(i).Notify event_mask
Next i
End Sub
Finally, if views may eventually be destroyed by a program, the model should provide an UnregisterView subroutine. When a view no longer needs to be informed of the models events, the program should use UnregisterView to remove it from the models list of views. This is important for preventing the model from trying later to invoke the Notify subroutine of an object that no longer exists.
Public Sub UnregisterView(view As Object)
Dim i As Integer
For i = 1 To Views.Count
If view Is Views.Item(i) Then
Remove this view and its event mask.
Views.Remove i
Events.Remove i
Exit Sub
End If
Next i
End Sub
At first one might think a view objects Class_Terminate event handler would be an ideal place to call UnregisterView. Then when the program destroyed an object, the call would happen automatically. Unfortunately, this does not work. Visual Basic does not invoke an objects Class_Terminate event handler until the object is actually destroyed. Visual Basic will destroy an object only when the program contains no more references to the object. Because a view object is included in the models list of views, the program contains a reference to the object so the Visual Basic will not destroy it. Therefore, the Class_Terminate event will not occur, so the call to UnregisterView will not happen. To destroy a view object correctly, the program must first call UnregisterView and then destroy the object. The following code shows how a program could destroy a view of the MyView class
Dim my_view As MyView
:
Initialize my_view, register it, etc.
Set my_view = New MyView
:
Destroy my_view.
TheModel.UnregisterView my_view
Set my_view = Nothing
Model Summary In summary, the model class must understand the application data. It must provide subroutines, functions, and property procedures that allow other parts of the program to view and modify the data. Finally, it must notify views when the data changes. The model does not need to know why another part of the program needs to view or modify the data. It also does not need to understand why views are interested in different events. For example, when it changes the selected date, the model notifies the views that are interested in that event. It does not understand the complex series of changes this may cause. ViewsA view object has only one responsibility: to provide some sort of display of a model. A view uses the models public routines and property procedures to obtain information about the data so it can present an appropriate display. Usually this display is visible through a user interface, though in theory the display could provide information to another program rather than the user. The view should be registered with the model so it receives notification whenever a change to the data would affect the views display. When the view receives notification, it should update its display as necessary. Before a view object can receive event notifications, the program must register the view with the model, specifying the events that it finds interesting. A reasonable place to do this is in a view class subroutine named Initialize. This routine can take as parameters the model and any other information the view needs for initialization. The DateLabelV class in AppointmentBook is a very simple view that manages the date display label above the daily appointment area. This label displays the currently selected date textually. When the user drags the month areas scroll bar slider, this label displays the date that would be selected if the user were to release the slider. AppointmentBooks main form CalendarForm uses code similar to the following to declare and initialize the variable TheDateLabelV. This is the date label view object used by the program to manage the date label.
Declare the view.
Private TheDateLabelV As New DateLabelV
:
Initialize the view.
TheDateLabelV.Initialize TheCalendarModel, DateLabel
The Initialize subroutine for the DateLabelV class takes as parameters the model and the label control that will later display the selected date. The routine saves references to these for later use. It then registers itself with the model indicating that it should be notified when the selected date changes and when the temporary date changes. The temporary date is the date selected while the user is dragging the month areas scroll bar slider.
Public Sub Initialize(model As Object, ctl As Label)
Save the label control for later use.
Set TheLabel = ctl
Save the model for later use.
Set TheModel = model
Register with the calendar model.
model.RegisterView Me, _
CAL_SelectedDateChanged Or _
CAL_TemporaryDateChanged
End Sub
ControllersA controller manipulates the data in a model. The controller must manipulate the data indirectly using the public routines provided by the model. Those routines modify the data as needed and then notify any views that are interested in the change. If a controller were to modify the data directly, the model would not have the opportunity to notify the views. Sometimes a controller may need to make several changes to the data before the model notifies the views. When performed individually, the changes might cause notification to be sent several times to the same views. That, in turn, might force a view to redraw itself several times unnecessarily. In cases like this, it is tempting to provide routines in the model that do not perform view notification. The controller would use those routines until the last modification, when it would use the normal data modification routine. This is not a wise practice. If the last call to the normal modification routine is omitted or later removed, the views will never be updated. A better solution is to create a new model subroutine that performs all of the data modifications in a single subroutine call and then notifies the views when it is finished.
|
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|