Friday, October 22, 2004

Datasource for DataGrid

Our custom DataSource for Microsoft .Net DataGrid is finally working, fully!! I guess Chandra will not be able to find one more bug ;)
The problem was with the Allow New property.When you click in the last row of grid with asterisk, it changes to a pencil image.As soon as you click in the last row, the 'AllowNew' function of datasource (IBindingList.AddNew) is called.This adds a new object to the internal collection of data source. This object is in temporary state and its addition to datasoure will be cancelled if the user makes no changes to it and selects any other row or when he presses escape key. When you start typing in the last row a new row with asterisk sign will be added and the state of the object added to thecollection will be made permanent. The problem arises when the user does not makes any change and selects some already existing row.
In our datalist class as soon as the AddNew function is called we add an object and Raise an OnListChnaged event.But when the user cancels the operation the newly added row is removed from the Grids Internal Collection but there is no way we can get notified about this.The missing communication link can be taken care of by implementing IEditableObject in the class whose object will be stored in the DataList.But still there are problems. The DataGrid calls the item's IEditableObject.CancelEdit() function when you press ESC on an new row or activate a different row. But it never fires the ListChanged event nor does it remove the item from the data list. So there is no way for the list to remove the invalid new row from the data list.A new flag should be added, (called isNew) to the object that will be stored in the DataList.This should be exposed by either making it public or by using an internal property.By default it will be false but when a new object is added by using IbindingList.AddNew then it will be set to true using the exposed property.Check the implementation for more details and use of 'isNew'. As I don't feel like writing about it :)
For once the documentation/sample in MSDN are misleading and do not work.
If you want to pass your own collection as DataSource for MS .NET DataGrid then implement IBindingList interface in your collection. If you want a strongly typed collection then use CollectionBase class as your base class otherwise use ArrayList. Most importantly, do not forget to implement IEditableObject interface in your classes whose objects you are going to store in your own collection.

1 comment:

Annie Calvert said...

Its an excellent article, to the point tutorial.You have got some class on this site.