Browse DevX
Sign up for e-mail newsletters from DevX


Coordinate User Interface Development with VB.NET and the MVC Pattern : Page 4

Use VB.NET and the MVC pattern to create a user interface framework for collaborative development. By cleanly isolating display elements from data, the MVC pattern lets multiple programmers develop and modify UI functionality at the same time without problems.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Synchronizing Changes
When a user clicks one of the menu items, the framework fires the viewCustomerList_Click event-handler, which displays a Customer List View.

objView = New frmCustomerListView() objView.Initialize(Me.Model) If Not Me.Container Is Nothing Then objMDIPArent = Me.Container objView.MdiParent = objMDIPArent End If objView.Display()

If the user changes any data in the screen, the Mediator relays the changed data to the Controller to be validated and processed. To see how this works, change the name of one of the customers by editing the label in the List View. When you press Enter or click away from the label, the AfterLabelEdit event goes off.

Dim objListItem As System.Windows.Forms.ListViewItem Dim objEvent As MVCLibrary.clsEvent objListItem = lvwCustomers.Items(e.Item) objEvent = New MVCLibrary.clsEvent() With objEvent .Name = "CustomerNameChange" .Value = e.Label .ValueEx = objListItem.Tag End With Try mobjController.HandleEvent(objEvent) Catch objError As System.Exception MsgBox(objError.Message) e.CancelEdit = True End Try

The AfterLabelEdit event creates a new clsEvent instance and populates it with information about the changed data. Then the View notifies its Controller of the change by calling the HandleEvent method. The notification call occurs within a Try...Catch block because the Controller may return an error if the data is not valid. For example, the business rules might state that the customer name cannot be blank. The Controller's HandleEvent method validates the Event's value, catches the error condition, and raises an error.

Public Overrides Sub UpdateData(ByVal NewEvent As MVCLibrary.clsEvent) Dim objCusotmers As clsCustomers Dim objCustomer As clsCustomer Select Case NewEvent.Name Case "CustomerNameChange" If Len(NewEvent.Value) < 1 Then Err.Raise("50000", "clsCustomerListController", _ "Name cannot be blank") End If objCusotmers = Me.Model objCustomer = objCustomers.Item (NewEvent.ValueEx) objCustomer.Name = NewEvent.Value End Select End Sub

If the data is valid, the Controller makes changes to the Model by retrieving the appropriate Customer instance from the collection and changing its Name property.

When this change occurs, it must be propagated to other Views that might be relying on the data. Therefore, in clsCustomer, the Name property's Set code notifies any observers that a change has occurred by creating a new instance of clsEvent, setting its properties, and passing the changes along using the parent's (clsCustomers) Notify method. The Notify method is a member of the base class clsSubject. It cycles through the list of attached observers and sends the event on to them.

Public Property Name() As String Get Name = mstrName End Get Set(ByVal Value As String) Dim objEvent As MVCLibrary.clsEvent mstrName = Value objEvent = New MVCLibrary.clsEvent() With objEvent .Name = "CustomerDataChanged" .Value = Me End With mobjParent.Notify(objEvent) End Set End Property

Views all register with the Model when they are initialized. That means that any other currently displayed View will receive events and be able to adjust its information immediately. There's no need for the user or the application to refresh the screen to see the new data, everything happens in real-time.

To see this in action, open up two or three instances of the Customer List form, change the name of a customer on one of the lists and press enter. You'll see the name updated immediately in all Views.

The sample project also has a New Customer View you can experiment with. To activate this view, click File, then New, then Customer. The New Customer View displays differently than the Customer List View; it's a modal form, not an MDI child, but it behaves the same way. When you click OK to create a new customer, its Controller validates the entered data. If the data is valid, the Controller makes modifications to the Model, which in turn notifies all attached observers about the new customer. Try it out and see what happens.

I hope the sample helps you solve the problem of coordinating multiple programmers working simultaneously on a single UI. Although the sample project code is not robust enough to include directly in a real project, you should be able to use it as a starting point. There are several things you can do to improve the sample project, such as:

  • Load the list of Mediators from an XML file, and create them using dynamic binding.
  • Replace the even names with enumeration values.
  • Add a Windows menu that lists all open windows, and lets you tile and cascade them.
  • Give windows the ability to trap standard menu and toolbar events (such as Save from the main menu)

Mark D'Aoust is Vice-President of Research and Development for OSTnet OpenSource Technologies Inc (www.ostnet.com), a Montreal, Quebec (Canada) based company that develops tools to enable software reuse. Marc can be reached at marc@ostnet.com
Thanks for your registration, follow us on our social networks to keep up-to-date