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.