Friday, August 22, 2008

StockSample: The View

This post is part of my series on the Windows Forms Model View Presenter with Data Binding sample program I wrote I call StockSample.

In the 20080818 snapshot of the StockSample program, I have a shell program (the main form) and a single view that is in a module called “StockLister”.  I’m using some of the same terminology from CAB (Composite UI Application Block).  The StockSample program doesn’t use anything other than the .NET base class library (and NUnit and DockPanel Suite).  An application such as this might be better hosted on something like CAB, or you can develop your own simpler framework that is specific to your application.  The benefit of going with an application framework that’s already developed is that (1) you don’t have to do it yourself and (2) you can more easily talk to someone else about your application.  For something that will be developed and maintained by multiple developers over time, using something like CAB might be easier to get them trained up since they can troll the Internet for documentation and starter examples.

The module and the view represent a feature (or set of features) that tell a story (or part of a story).  The view is what the user sees and interacts with.  Most applications will have at least one view for the user to interact with.  In the StockSample program, the module is called “StockLister” and its purpose is to allow the user to see all the stocks that are available, their prices, and the timestamp of the last price update.  The view interface IStockListerView is very simple:

   1:  public interface IStockListerView
   2:  {
   3:      IStockList Stocks { get; set; }
   4:  }

It accepts the interface reference to the IStockList we have in the model.  For this simple example, I made it so that the view can consume the model interface directly without modification.  In a more complex application, you may need to map the model data into the view data in different ways (this is handled by the Presenter which I will discuss in a later post).  For now, we will work with the simple example.  Notice that there is no reference to anything in WinForms or ASP.NET.  This view interface is a contract for a particular feature of the application (in this case, allowing the user to see a list of stocks with updated prices).

In the StockSample, this view is implemented as a WinForms UserControl.  Here are the steps I took to build this control:

  1. In Visual Studio, create a new UserControl and call it “StockListerControl”.
  2. Make the control area bigger and drop a DataGridView on it.  Set the DataGridView DockStyle to Fill.
  3. Click on the “Data” menu, then click “Add New Data Source…”.
    Add New Data Source option in Visual Studio
  4. Select “Object”, click “Next”.
  5. Drill down the tree (this tree is built from the classes in the project and external references) and select the “IStockList” interface.  Click “Next”.
    Where to find the IStockList data object to bind to
  6. Click “Finish”.
  7. Now, click on the DataGridView, then find the “Smart Tag” in the top right (the little white box with the black chevron), click it, then click the drop-down that says “Choose Data Source”.
  8. Drill down into “Other Data Sources”, “Project Data Source”, through a namespace or two, then click “IStockList”.
    Where to select the IStockList data source for the DataGridView
  9. The grid should be pre-populated with all the properties of IStock.  Based on how I wrote the interface for IStockList, Visual Studio figured out that this is a list of IStock objects.
    VisualStudioIStockListDataSourceDescription
  10. You can edit the grid columns to change the titles, data format, and ordering of the columns to make it look pretty.
    VisualStudioStockListerControl
  11. You’ll notice a new component added to your UserControl at the bottom of the screen, I renamed it to “iStockListBindingSource” to look nicer.

Now that we have the control created, we write a little bit of code:

   1:  public partial class StockListerControl
   2:      : UserControl, IStockListerView
   3:  {
   4:      public StockListerControl()
   5:      {
   6:          InitializeComponent();
   7:      }
   8:   
   9:      StockSample.Core.Data.IStockList _stocks;
  10:   
  11:      public StockSample.Core.Data.IStockList Stocks
  12:      {
  13:          get     {  return _stocks; }
  14:          set
  15:          {
  16:              if (this.Stocks == value) return;
  17:   
  18:              _stocks = value;
  19:              iStockListBindingSource.DataSource = _stocks;
  20:          }
  21:      }
  22:  }

The only meat here is line 19.  The “iStockListBindingSource” is what was created when we added the data source to the grid.  The Forms designer already connected the grid to the binding source, now we just need to supply the data source to the binding source to feed to the grid.  Due to the way we implement the model (using BindingList<T>), we get list update events for free.

At this point, all we’d need to do to show a simple form with just this control is to drop the control on a form, create an instance of the stock list, and pass the IStockList reference to the control.  Coincidentally (or not), that is exactly what the Presenter does.

The Visual Studio Forms Designer has a lot of easy to use features for data binding.  You can perform your own experiments on object data sources in Windows Forms applications.  It makes it super easy to create a functional prototype application as well without touching a database.  At work, I took half a day to create a fairly functional data driven application and not have to write a bunch of UI code.  Most of the work was spent creating the Model layer, then throwing a UI together and wiring everything up was a snap.

Technorati Tags: ,,

Monday, August 18, 2008

StockSample: The Model's Interfaces

This post is part of my series on the Windows Forms Model View Presenter with Data Binding sample program I wrote I call StockSample.

One of the big things that is enabled by following the Model View Presenter pattern is "persistence ignorance".  For the model, I like to have POCO (Plain Old CLR Object) classes that represent the logical model that makes the most sense for the application.  This logical model might be different from the physical model if it makes the application easier to write.  Each of the model objects will also implement an interface that covers all the relevant publicly accessible properties, methods and events on the model types.  Interfaces will help with testability during development as you can create simpler test classes or use a mocking framework to create the desired test behavior.

In the current StockSample snapshot (20080818), I have one model, the Stock.  It has the following interface:

   1:  public interface IStock
   2:  {
   3:      string Name { get; }
   4:      string TickerSymbol { get; }
   5:      decimal CurrentPrice { get; }
   6:      DateTime LastUpdate { get; }
   7:  }

The Stock is special in that most of the application will not be modifying the stock information, but will be listening to changes to the stock.  I didn't make this interface inherit from INotifyPropertyChanged because the model class could use an alternative trigger for property change notifications (PropertyNameChanged events, for example).  The stock information will be populated and updated by the IStockProvider:

   1:  public interface IStockProvider
   2:  {
   3:      IStockList Stocks { get; }
   4:  }

Now that I think about it, I suppose a better name would be StockListProvider, I'll have to make those tweaks later.  The IStockList represents a collection of IStock objects:

   1:  public interface IStockList : IBindingList
   2:  {
   3:      IStock CreateNew(string tickersymbol, string name);
   4:      void Add(IStock stock);
   5:      IStock FindByTickerSymbol(string tickersymbol);
   6:      new IStock this[int index] { get; }
   7:  }

This interface has some more meat to it.  I inherit from IBindingList because I want to make sure we can bind this collection.  IBindingList is a bundle of interfaces that is necessary for binding a collection to places where a DataSet or DataView would typically go.  I'll go into more details about this later.

So, when dealing with the Model layer looking purely at the interfaces, we start with an IStockProvider.  The implementation of this is not important, all we care is that it provides is with an IStockList.  This list contains all the IStock instances that we will be able to use in our application.  The implementation of the IStockProvider will allow us to determine how we will actually get updated stock information.  The IStockList will tell us how many stocks there are and allow us to iterate on the list, and finally, the IStock will give us information on the stocks themselves.

Technorati Tags: ,,

StockSample: First Model View Presenter Sample Posted

After a long hiatus, I've created a new sample program for Windows Forms Model View Presenter pattern with data binding.  This example is not what I would call "best practices" but rather a simplification of the concepts to break it down to the most basic components.

The example is a program that is used to get stock price updates.  I wanted an example that I could do a lot of different visualizations and views / operations that just about anyone can understand.  I know that Glenn Block posted on the Composite UI WPF guidelines here (http://blogs.msdn.com/gblock/archive/2008/07/03/composite-application-guidance-is-live.aspx) and they also have a stock trading reference application.  The goal of my sample is to show a very simple example of Model View Presenter with Windows Forms and data binding.  There is no Inversion of Control container, no database, and no extra frills.  The sample is done in Visual Studio 2008 Express Edition (which is all you need to build / run it).  The only external libraries that are referenced are NUnit (http://www.nunit.org) and Weifen Luo's DockPanel Suite (http://sourceforge.net/projects/dockpanelsuite/).

You can get the source from my google code project here, see this link for instructions on checking out code from my repository (http://code.google.com/p/garoyeriazarian/source/checkout).  The code is in the StockSample/tags/Snapshot20080818 folder.  I'll be updating the trunk periodically with extra functionality.  There are some tests... I'm still trying to get the hang of Test Driven Development.

I'll have a series of posts following talking about parts of the sample and as I build more onto it, I'll talk about those and link to the new snapshots.  You can then use your favorite Subversion client to see what exactly is different.  If you have any specific requests on things you want to see, let me know and I'll try to work it into the sample.

Technorati Tags: ,,