About Me

Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

Dealing with drop down lists with the MVP pattern

Archive

Blogroll

 Agile Developer Venkat's Blog
 Ayende @ Blog
 B#
 Barry Gervin's Software Architecture Perspectives
 Boy Meets World
 Brad Abrams
 Canadian Developers
 Christopher Steen
 Claritude Software News
 Clemens Vasters: Enterprise Development and Alien Abductions
 Coding Horror
 Coding in an Igloo
 Dare Obasanjo aka Carnage4Life
 Darrell Norton's Blog [MVP]
 David Hayden [MVP C#]
 Don Box's Spoutlet
 Eric Gunnerson's C# Compendium
 EZWeb guy: Jeffrey Palermo [C# MVP]
 Fear and Loathing
 Generalities & Details: Adventures in the High-tech Underbelly
 Greg Young [MVP]
 Greg's Cool [Insert Clever Name] of the Day
 IanG on Tap
 Ingo Rammer's Weblog
 ISerializable - Roy Osherove's Blog
 James Kovacs' Weblog
 Jason Haley
 Jean-Luc David
 Jeremy D. Miller -- The Shade Tree Developer
 JetBrains .NET Tools Blog
 Jimmy Nilsson's weblog
 John Bristowe's Weblog
 John Papa [MVP C#]
 Jon Skeet's Coding Blog
 JonGalloway.ToString()
 Jump the Fence or Walk Around
 Lambda the Ultimate - Programming Languages Weblog
 Larkware News
 Lutz Roeder
 Marquee de Sells: Chris's insight outlet
 Martin Fowler's Bliki
 Mike Nichols - SonOfNun Technology
 MSDN Magazine - .NET Matters
 MSDN Magazine - All Articles
 OdeToCode Blogs
 Onion Blog
 Planet TW
 Raymond Lewallen [MVP]
 Rockford Lhotka
 RodMan's Corner
 Roger Johansson's blog
 Sahil Malik - blah.winsmarts.com
 Sam Gentile's Blog
 Scott Bellware [MVP]
 Scott Hanselman's Computer Zen
 ScottGu's Blog
 secretGeek
 Service Station, by Aaron Skonnard
 Signum sine tinnitu--by Guy Kawasaki
 Stephen Toub
 Steve Eichert's Blog
 Steven Rockarts
 The Blog Ride
 The Coding Hillbilly
 The Daily WTF
 TheServerSide.net: News
 Tim Gifford
 Vance Morrison's Weblog
 you've been HAACKED

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 407
This Year: 132
This Month: 3
This Week: 0
Comments: 1082

 Tuesday, May 02, 2006
Tuesday, May 02, 2006 3:25:51 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C# | Patterns )

I just had a great question asked by David Woods about one scenario that often comes up when utilising the Model View Presenter pattern:

Q: How do you deal with drop down lists? They vary from web to windows and I want to refactor my app so that it can use either

A: The code for this post shows one solution to the problem. An interface (ILookupList) is created to abstract the details of the UI specific list controls from the presenter:

 

namespace Lists.Web.Controls.Test
{ public interface ILookupList
{ void Add(ILookupDTO dto); void Clear(); } }

 

One concrete implementation of this interface is the WebLookupList class:

 

using System.Web.UI.WebControls;

namespace Lists.Web.Controls.Test
{ public class WebLookupList : ILookupList
{ private readonly ListControl listControl; public WebLookupList(ListControl listControl) { this.listControl = listControl; } public void Add(ILookupDTO dto) { listControl.Items.Add(new ListItem(dto.Text, dto.Value)); } public void Clear() { listControl.Items.Clear(); } } }
Notice how all the WebLookupList does is delegate to an actual “Web” ListControl. ListControl is the base class for both DropDownList and ListBox, so it is useful to use the superclass in this case. The last piece of the puzzle is the LookupCollection class:
using System.Collections.Generic;

namespace Lists.Web.Controls.Test
{ public class LookupCollection
{ private readonly IEnumerable<ILookupDTO> dtos; public LookupCollection(IEnumerable<ILookupDTO> dtos) { this.dtos = dtos; } public void BindTo(ILookupList list) { list.Clear(); foreach (ILookupDTO dto in dtos) { list.Add(dto); } } } }
A LookupCollection gets instantiated with an IEnumerable<ILookupDTO> and can then be told to bind itself to any ILookupList. The ILookupDTO interface is just an interface that can be implemented by objects that want to be used as values in a lookup list. With all of these pieces in place it becomes relatively trivial to populate a list on a web page with all of the customers in the system. Take a look at an interface for such a view:
namespace Lists.Web.Controls.Test
{ public interface IViewContactView
{ ILookupList Contacts { get;} } }

Notice that the Contacts property is readonly. A presenter that can work with this view looks as follows:

 

using System.Collections.Generic;

namespace Lists.Web.Controls.Test
{ public class ViewContactsPresenter
{ private IViewContactView view; public ViewContactsPresenter(IViewContactView view) { this.view = view; } public void Initialize() { new LookupCollection(GetAllContacts()).BindTo(view.Contacts); } public IEnumerable<ILookupDTO> GetAllContacts() { for (int i = 0; i < 20; i++) { yield return new ContactDTO(i.ToString("Name 0"), i.ToString("Address 0"), i.ToString()); } } } }
In this example, assume that the GetAllContacts method actually lives in a service layer. The code in the Initialize method is now taking advantage of the LookupCollection class to populate the list on the view. The resulting code-behind for a web page becomes much tighter
using System;
using System.Web.UI;
using Lists.Web.Controls.Test;

public partial class _Default : Page,IViewContactView
{ ViewContactsPresenter presenter; protected void Page_Load(object sender, EventArgs e) { presenter = new ViewContactsPresenter(this); if (! IsPostBack) { presenter.Initialize(); } } public ILookupList Contacts
{ get { return new WebLookupList(this.contactDropDown); } } }

Hope this brief explanation, along with the accompanying source code, gives you a place to start David!!

 

For those of you who are curious about the order I wrote the tests (as this was done using TDD) here it  is:

  • 1)WebLookupListTest.cs – ShouldAddItemToUnderlyingList
  • 2)WebLookupListTest.cs – ShouldClearUnderlyingList
  • 3)LookupCollectionTest.cs – ShouldBindToLookupList

Those 3 tests alone helped drive out the interfaces,classes etc. I did not write tests for the presenter and the view as MVP was not the main focus of the post, as much as how to have the presenter talk to the list controls. If you have any questions or feedback, please don’t hesitate to ask.

 

Resources:


TODO