Click here to Skip to main content
13,355,018 members (56,755 online)
Click here to Skip to main content
Add your own
alternative version


75 bookmarked
Posted 23 Apr 2003

Databinding the SqlTypes

, 1 May 2003
Rate this:
Please Sign up or sign in to vote.
Databinding the SqlTypes using the PropertyDescriptor class and the ITypedList Interface


Lets say we have an object, which wraps some data from the database. Eventually we want a collection of them displayed in a DataGrid or some other bindable component. For the purpose of this discussion, we will have a class that wraps a DataRow, and properties that wrap its cells.

public class DataRowWrapper
  private DataRow dataRow;

  public DataRowWrapper(DataRow dr)
    this.dataRow = dr;

  public int ID
    get { return (int) this.dataRow["ID"]; }

  public DateTime dtStamp
    get { return (DateTime) this.dataRow["dtStamp"]; }
    set { this.dataRow["dtStamp"] = value; }

The Problem

This example may look all well and good, but unfortunately a cell can be null, and an int or DateTime cannot! Herein lies the problem. This code will throw exceptions on any null data, and we cannot assign null to the values. So we can use SqlTypes which allow null values.

public SqlDateTime dtStamp
    if (this.dataRow.IsNull("dtStamp"))
      return SqlDateTime.Null;
      return new SqlDateTime((DateTime)this.dataRow["dtStamp"]);
    if ( value.IsNull )
      this.dataRow["dtStamp"] = DBNull.Value;
      this.dataRow["dtStamp"] = value.Value;

So now we have ruined it for data binding. Data binding does not work for SqlTypes. SqlTypes are not editable. I see this as a big oversight, but there is a solution - PropertyDescriptors.

The Solution

Property descriptors allow us to expose the SqlTypes underlying type ONLY through data binding, and leave everything else the same for normal use of the object. One problem with property descriptors is that we need to implement ITypedList for it to be any use. ITypedList contains the method signature GetItemProperties(), which we can return our own property descriptors with. We could write one property descriptor for each of the SqlTypes, but here’s an easier way.

public class SqlPropertyDescriptor : PropertyDescriptor
  public static SqlPropertyDescriptor GetProperty(string name, Type sqlType)
    Type baseType = sqlType.GetProperty("Value").PropertyType;
    ArrayList attribs = new ArrayList(TypeDescriptor.GetAttributes(baseType));
    Attribute[] attrs = (Attribute[])attribs.ToArray(typeof(Attribute));
    return new SqlPropertyDescriptor(name,attrs,sqlType,baseType);

  private Type SqlType;
  private Type BaseType;

  protected SqlPropertyDescriptor( string name,Attribute[] attrs,
    Type sqlType, Type baseType ) : base(name,attrs)
    SqlType = sqlType;
    BaseType = baseType;


  public override void SetValue(object component,object value)
    PropertyInfo pi = component.GetType().GetProperty(this.Name);
    Object o;
    if ( value == DBNull.Value )
      o = component.GetType().GetField("Null", BindingFlags.Static
        | BindingFlags.Public | BindingFlags.GetField).GetValue(component);
      o = pi.PropertyType.GetConstructor(new Type[]{BaseType}).Invoke(
        new Object[]{value});
    pi.SetValue(component,o, null);

  public override object GetValue(object component)
    object Property = component.GetType().GetProperty(this.Name).GetValue(

    if ( (bool)Property.GetType().GetProperty("IsNull").GetValue(Property,
        null) )
      return DBNull.Value;

    return Property.GetType().GetProperty("Value").GetValue(Property,null);

Here we can see that I have overridden the SetValue() and GetValue(), and since they pass around the data type object, they can handle nulls. I use some reflection to achieve the desired result. SetValue() can put null into the property, and GetValue() can return a null if need be. To use the property descriptors, we must implement ITypedList in our collection, and return our custom property descriptor for all the properties where they are SqlTypes. In my code, I call the following method to replace the property descriptors.

protected PropertyDescriptorCollection GetPropertyDescriptorCollection(
  ArrayList properties )
  if ( properties == null || properties.Count == 0 )
    return new PropertyDescriptorCollection(null);

  ArrayList output = new ArrayList();

  foreach ( PropertyDescriptor p in properties )
    if ( p.Attributes.Matches(new Attribute[]{
      new BindableAttribute(false)}) ) continue;

    if ( p.PropertyType.Namespace == "System.Data.SqlTypes" )
      // create the base type property descriptor
        p.Name, p.PropertyType ) );
  return new PropertyDescriptorCollection(

So, now we have a class with properties that are database and null friendly, we can show it in a grid and edit it, and the methods written are generic enough that we can use then on all the SqlTypes.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Dan Glass
Australia Australia

You may also be interested in...

Comments and Discussions

GeneralBinding data in database using a Class Pin
madhan singh raja27-Mar-06 0:59
membermadhan singh raja27-Mar-06 0:59 
GeneralVery nice but!!! Pin
Brandon Parker14-Dec-04 23:46
memberBrandon Parker14-Dec-04 23:46 
QuestionAnyone done this in a web app? Pin
zsoltvotin19-May-04 5:34
memberzsoltvotin19-May-04 5:34 
AnswerRe: Anyone done this in a web app? Pin
ibrahim rodriguez29-Jun-05 15:59
memberibrahim rodriguez29-Jun-05 15:59 
QuestionHow did you figure it out? Pin
jjreilly26-Sep-03 2:29
memberjjreilly26-Sep-03 2:29 
AnswerRe: How did you figure it out? Pin
小康3-Apr-04 2:14
member小康3-Apr-04 2:14 
GeneralRe: How did you figure it out? Pin
Dan Glass4-Apr-04 14:11
memberDan Glass4-Apr-04 14:11 
GeneralSetting Values to Null Using Binding Pin
SharZoe5-Jun-03 7:04
memberSharZoe5-Jun-03 7:04 
GeneralApplying it to a single business object Pin
Paulo4-May-03 13:53
memberPaulo4-May-03 13:53 
GeneralRe: Applying it to a single business object Pin
rahtrow4-May-03 17:15
memberrahtrow4-May-03 17:15 
GeneralRe: Applying it to a single business object Pin
DBuckner6-May-03 18:24
memberDBuckner6-May-03 18:24 
GeneralRe: Applying it to a single business object Pin
Dan Glass7-May-03 8:33
memberDan Glass7-May-03 8:33 
GeneralRe: Applying it to a single business object Pin
Paulo13-May-03 11:42
memberPaulo13-May-03 11:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.180111.1 | Last Updated 2 May 2003
Article Copyright 2003 by Dan Glass
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid