Building Model-View-Presenter applications with MVC#. Part 2: Silverlight and Tasks

Published: 7/16/2008
By: Oleg Zhukov

Oleg Zhukov talks about building applications with MVC#.

Contents [hide]

Introduction

Nowadays user interfaces are becoming more and more complex. And with the appearance of RIA (Rich Internet Application) technologies (e.g. Silverlight) even Web interfaces are gaining considerable complexity. A good way of fighting against this complexity is using architectural patterns, such as Model-View-Presenter.

In my previous article (read it up to the "Presentation" section prior to going on with this article) we got acquainted with MVC# - a framework which simplifies the usage of the Model-View-Presenter pattern by developers. There we have concerned an execution of a single task and have discussed interaction between task's views, its controllers and the task object itself. But one important question left uncovered is how two or more tasks interact with each other. This article considers an example of communication between tasks in MVC# Framework. The presentation platform we are using in this example is a brand new Silverlight 2.0 beta 2 (which is supported by MVC# starting from version 0.8).

Note:

The source code of this example can be found under "Examples\TasksInteraction\" subfolder of the MVC# root folder. Silverlight presentation project is in the "Examples\TasksInteraction\Presentation\Silverlight" folder. The framework itself can be downloaded from www.MVCSharp.org/download.aspx.

Application logic

The example we'll examinehere deals with a list of employees and allows to award a bonus to each employee. Bonus awarding procedure requires entering several options which determine the resulting bonus sum.

We will construct the application of two tasks: one for browsing through the list of employees (main task), the other for awarding a bonus to a particular employee (bonus award task).

Main Task

The main task will include a single view showing a list of employees, which will be activated on the task start:

Besides a list of employees the employees view will contain a button (or menu item or whatever else) for starting a bonus award task. However the employees view will not start this task itself. Instead, according to the MVP pattern, this work should be delegated to the associated EmployeesController instance.

Employees Controller

As decided above the Employees controller class should contain a method (say, AwardBonus()) for starting a bonus award task. For this task to execute, it needs to know the employee to be awarded. That is why we pass the current employee object to the task starting procedure:

After finishing its execution the bonus award task should return control to the main task. Thus a reference to the main task should also be passed to the bonus award task:

Next, we will discuss the AwardBonusTask class and corresponding controller classes.

Award Bonus Task

The bonus award task will have two views. The main view will have edit boxes to choose some basic options and an "OK" button to award a bonus and return to the main task. The second view will be used for entering advanced options:

When started, the bonus award task receives the employee to be awarded and the originating task as input parameters. These parameters are then stored in the task's public fields. After that the main view gets activated:

Award Bonus Main Controller

In the bonus award main view when a user decides to award a bonus and clicks "OK" the control should be passed to the ABMainController.DoAwardBonus method. This method calculates the bonus sum, assigns it to the employee and returns control back to the main task:

Here we do not need to pass anything back to the main task. In more complicated situations, however, the originating task's behavior might depend on parameters passed back to it by nested tasks.

A few changes should also be made to the MainTask class. The point is that Navigator.NavigateDirectly(...) would not activate a view if it is already marked as current for the task. That is why calling MainTask.OnStart(...) will have no effect if returning back to the main task. Instead, we should use Navigator.ActivateView(...), as it will activate a view even if it is current for the task.

As we can see tasks communication is done by simply invoking task start methods with necessary parameters. For existing task instances we use Task.OnStart(...) method, for new tasks TasksManager.StartTask(...) is used.

Advanced Options Controller

This controller simply saves options entered in the advanced options view to the task's public fields, and then navigates back to the main award bonus view:

Presentation

Employees view

Views for the Silverlight platform should inherit the UserControlView class. Therefore we will first create an empty UserControlView descendant using the following XAML markup:

Then we should add a data grid to show the list of employees and an "Award Bonus" button:

Figure 1: The “Award Bonus” button

The “Award Bonus” button

Note that we are using a layout with two columns so that the view occupies the entire window space. Otherwise the contents of underlying views can become visible, which is unwanted.

The "Award Bonus" button handler will do nothing but delegate processing to the appropriate controller's method. As for the IEmployeesView implementation, it is very straightforward as seen from the code below:

We will also reload the grid's data on the view activation:

The last thing required here is to associate the created view class with the "Employees" view. We achieve it by applying the [View] attribute to the view class:

That is all with the employees view. Next we will design two views for the bonus award task.

Bonus award views

First, let us design the award bonus main view. As above, we will start with an empty UserControlView descendant:

The view will look as a rounded dialog box on a semi-transparent background:

Figure 2: The rounded dialog box

The rounded dialog box

The advanced options view will be shown inside the award bonus main view, in the rounded dialog box. That is why the markup above contains the <TI:ABAdvancedOptionsView ...> element. It should be hidden at first (Visibility="Collapsed") and its name should be specified (ViewName="Advanced Options View") for the framework to properly identify it.

Below is the advanced options view markup:

Figure 3: The “Advanced Options” view

The “Advanced Options” view

Now let's turn our attention to the views' code-behind files. The award bonus' main view class should implement the IABMainView interface and should handle the "Advanced Options" link and the "OK" button clicks. As before, we also use the [View] attribute for registering the view:

The advanced options view class should implement the IABAdvancedOptionsView interface and should handle the "OK" button click. Moreover it should hide itself each time it is deactivated to reveal the parent view controls. Since we have explicitly placed this view inside the award bonus main view (see the XAML of the award bonus main view above), the [View] attribute is not required here:

Finally, we should write the application startup method. Inside it the main task should be started, obviously:

Conclusion

Tasks interaction in MVC# is no harder than an ordinary interaction between two objects: one tasks just passes needed data to the other task's OnStart(...) method (either directly or by calling TasksManager.StartTask(...) if the task instance does not exist yet). Using MVC# with Silverlight platform is easy as well: everything needed is to design view classes, just like for other presentation platforms (Windows and ASP.NET forms).

Please visit the link at the below url for any additional user comments.

Original Url: http://dotnetslackers.com/articles/aspnet/Building-Model-View-Presenter-Applications-with-MVC--Part-2-Silverlight-and-Tasks.aspx