Thursday, September 20, 2007

DevExpress XPO, DropDownList and Custom Formatting in DetailsView's ItemTemplate

It is a common scenario to put a DropDownList into GridView's or DetailsView's Item Template. Since most of the time we use object-oriented architecture, the DropDownList's data source is a business method which returns list of business entities.

Long ago, when we've faced this scenario for the first time, we had to solve the formatting issue - when binding a list to the DropDownList, you specify DataTextField and DataValueField:

   1: <asp:DropDownList 
   2:     ID="TheDropDownList" 
   3:     runat="server" 
   4:     DataSource="<%# DataProvider.BusinessObjects %>" 
   5:     DataTextField="Name" DataValueField="ID" /> 

Issues occur when you need the items to be formatted in a custom way.


The most convenient and coherent method of adding custom formatting is to add a dummy property to the business object class:



   1: public class BusinessObject : IFormattable {
   2:  
   3:   private string name;
   4:   public string Name { ...
   5:   }
   6:  
   7:   public BusinessObject This {
   8:     get { return this; }
   9:   }
  10:  
  11:   public string ToString( string format, IFormatProvider formatProvider )
  12:   {
  13:     switch ( format )
  14:     {
  15:       case "s" :
  16:         return ...;
  17:       default :
  18:         return this.Name;
  19:     }
  20:   }
  21: }

so that you can force custom formatting of your business objects inside the DropDownList like this (note the This value for the DataTextField property) :



   1: <asp:DropDownList
   2:   ID="TheDropDownList"
   3:   runat="server"
   4:   DataSource="<%# DataProvider.BusinessObjects %>"
   5:   DataTextField="This" DataValueField="ID"
   6:   DataTextFormatString="{0:s}" />

This worked like a charm for us, well until few days ago when we've tried the same on business objects persisted with DevExpress XPO



   1: public class BusinessObject : XPObject, IFormattable
   2: {
   3:     public BusinessObject This
   4:     {
   5:         get
   6:         {
   7:             return this;
   8:         }
   9:     }
  10:  
  11:     ...

and instead of custom formatting I got DevExpress.XPO.XPCollection(14) Count(1), DevExpress.XPO.XPCollection(15) Count(1) ... instead of custom formatted descriptions.


After over 2 hours the battle was won. Following trick



   1: public class BusinessObject : XPObject, IFormattable
   2: {
   3:     public IFormattable This
   4:     {
   5:         get
   6:         {
   7:             return this;
   8:         }
   9:     }
  10:  
  11:     ...

does the job.


It turns out that XPObject inherits from XPCustomObject which inherits from XPBaseObject which has the ToString method defined and this is where the problem lies. Only changing the signature of the This property gives expected results.


The solution is, however, far beyond any explanation I am able to come up with.

No comments: