Freigeben über


Mobile MVC framework (part 3) - communicating with events

Just for people who are not comfortable with passing strings when notifiying the view or the controller, I've added the functionality to use events instead. You would not need to hook into the events explicitly because the controller will take care of this behind the scenes.

In order to demonstrate how to use this functionality I am going to modify the exising code for the SearchForm and the SearchController I created last time.

Let's start from adding the OnSearchEvent to the SearchForm class:

[PublishEvent("OnSearch")]

public event EventHandler<DataEventArgs<string>> OnSearchEvent;

As you can see the event declaration has a few peculiar things: I've applied the PublishEvent attribute which specifies the name of the event handler in the Controller. As a parameter I've used the DataEventArgs<T> class which is a part of the System.Mobile.Mvc assembly.

Since we are going to use the OnSearchEvent to notify the SearchController that the Search button has been clicked on the form, let’s modify the code on the button’s event handler to:

private void cmdSearch_Click(object sender, EventArgs e)

{

   if (OnSearchEvent != null)

    {

      // Raise the event and notify the controller

OnSearchEvent(this, new DataEventArgs<string>(txtSearch.Text));

    }

}

Now, we can move to the SearchController and add the event handler for the OnSearchEvent:

private void OnSearch(object sender, DataEventArgs<string> e)

{

     this.view.ViewData.Model.FilterData(e.Value);

     // Notify the view

     this.NotifyView();

The obvious positive outcome of this change is the ability to pass a strongly typed parameter between the view and the controller.

In order to communicate back to the view from the controller we can use exactly the same technique - declare the event with the PublishEvent attribute in the controller:

[PublishEvent("OnProductsUpdated")]

public event EventHandler ProductsUpdated;

private void NotifyView()

{

// Raise the event for view

if (this.ProductsUpdated != null)

{

this.ProductsUpdated(this, EventArgs.Empty);

}

}

Here are the final versions of the SearchView and SearchController after modifications:

public partial class SearchForm : ViewForm, IView<Products>

{

[PublishEvent("OnSearch")]

public event EventHandler<DataEventArgs<string>> OnSearchEvent;

public SearchForm()

{

InitializeComponent();

}

private void OnProductsUpdated(object sender, EventArgs e)

{

this.lstProducts.DataSource = this.ViewData.Model.ProductList;

}

#region IView<Products> Members

public new ViewDataDictionary<Products> ViewData

{

get;

set;

}

#endregion

private void cmdSearch_Click(object sender, EventArgs e)

{

if (OnSearchEvent != null)

{

// Raise the event and notify the controller

OnSearchEvent(this, new

DataEventArgs<string>(txtSearch.Text));

}

}

private void menuItemBack_Click(object sender, EventArgs e)

{

NavigationService.GoBack();

}

}

And the controller:

public class SearchController : Controller<Products>

{

[PublishEvent("OnProductsUpdated")]

public event EventHandler ProductsUpdated;

public SearchController(IView<Products> view) : base(view)

{

// Create an intance of the Products

Products products = new Products();

// Populate the list

products.PopulateList();

// Assign the Model

this.view.ViewData.Model = products;

// Notify the view of the changes

this.NotifyView();

}

private void OnSearch(object sender, DataEventArgs<string> e)

{

this.view.ViewData.Model.FilterData(e.Value);

// Notify the view

this.NotifyView();

}

private void NotifyView()

{

// Raise the event for view

if (this.ProductsUpdated != null)

{

this.ProductsUpdated(this, EventArgs.Empty);

}

}

}

You should probably notice the usage of the new class - NavigationService - the class I've just added to the framework and which takes care of caching of the controllers as well as showing them and navigating back and forth in the view stack. It implements

 a few helpful methods:

 

public static void Navigate(Controller controller)

public static void GoBack()

public static void GoForward() 

Download the project from here.

 

MVCDemoClient_events.zip

Comments

  • Anonymous
    October 17, 2008
    Just a remark to NavigationService - the GoBack/Forward approach looks really nice, but I'm missing some infrastructure for passing parameters between controllers. Let's say you have a ProductListController+View which displays a list of products in a grid. Than you have a ProductDetailController+View which should display detail information of product selected from the grid. How would you pass the selected Product from ProductListController to ProductDetailController? I'm using this class for navigation between controllers at the moment, but I don't like it completely - http://pastebin.com/m6375db0 Are you going to enhance the NavigationService class in some of the oncoming posts? Anyway thanks a lot for this MVC series - I appreciate it very much.

  • Anonymous
    October 17, 2008
    Good point. I will try to address this soon. Thanks... Alex

  • Anonymous
    November 04, 2008
    This is the part 4 of the series of the posts related to the Mobile MVC framework that I have described

  • Anonymous
    November 12, 2008
    Nestas coisas das teorias sobre a melhor forma de separar as diferentes camadas de uma aplicação, há