Mobile MVC framework (part 2)
Last time I showed you how to create a simple Login Form and pass the data between the View and Controller using ViewData dictionary. In this post I am going to show you how to pass a strongly typed data.
We will continue working with code sample we created last time. We are going to add a new form to the project that will display a list of items in the ListBox as well as to allow filtering the data in this ListBox by entering the filtering criteria in the TextBox. Let's add the new form to the project with the name SearchForm wich should look like that:
The Model
Let's add the Products class to the project which is goind to contain the List of products and implement a few simple methods to populate the list as well as a method to filter the list by the certain criteria:
/// <summary>
/// Model class
/// </summary>
public class Products
{
private List<string> productList;
public List<string> ProductList
{
get
{
return productList;
}
set
{
productList = value;
}
}
public string ProductType { get; set; }
public void PopulateList()
{
productList = new List<string>();
productList.Add("Chicken");
productList.Add("Bread");
productList.Add("Tomato");
productList.Add("Cucumbers");
productList.Add("Butter");
productList.Add("Cheese");
ProductType = "Food";
}
public void FilterData(string filter)
{
if (filter != "")
{
IEnumerable<string> result = productList.Where<string>(s => s.ToString() == filter);
this.productList = result.ToList<string>();
}
else
{
PopulateList();
}
}
}
The next let's modify the SearchForm code file to inherit from ViewForm and implement the IView<TModel> interface. Initially I have implemented the ViewForm<TModel> class and thought that I would be able to inherit from it, but I hit the old bug in the Visual Studio form's designer that doesn't like the generics if you want to visual inheritance, so I had to resort to a few workarounds such as implement the IView<TModel> interface by the form:
public partial class SearchForm : ViewForm, IView<Products>
{
public SearchForm()
{
InitializeComponent();
}
#region IView<Products> Members
public new ViewDataDictionary<Products> ViewData
{
get;
set;
}
#endregion
}
Let's add the override for OnUpdateView to the form that will be called from the controller:
protected override void OnUpdateView(string key)
{
if (key == "Category")
{
this.lblProductType.Text = this.ViewData.Model.ProductType;
}
if (key == "Products")
{
// Bind the product list to the listbox
this.lstProducts.DataSource = this.ViewData.Model.ProductList;
}
}
and add the implementation for button event handler:
private void cmdSearch_Click(object sender, EventArgs e)
{
// Place the filter data into the ViewData
this.ViewData["Filter"] = txtSearch.Text;
// Notify the controller
this.OnViewStateChanged("Search");
}
Search Controller
When creating the SearchController we will derive it from the Controller<TModel> and make an appropriate calls to the Products class:
public class SearchController : Controller<Products>
{
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.view.UpdateView("Products");
}
protected override void OnViewStateChanged(string key)
{
switch (key)
{
case "Search":
string filter = this.view.ViewData["Filter"].ToString();
this.view.ViewData.Model.FilterData(filter);
// Notify the view of the updates
this.view.UpdateView("Products");
break;
}
}
}
}
Download the project from here.