Binding to a Collection of Interfaces
There may be a case where you want to bind RadGridView to a collection of interfaces in order to be as abstract as possible or due to other reasons. RadGridView does not support this out of the box since when a new item is added its parameterless constructor is being invoked and interfaces cannot be created in such a way. The solution is to override the AddNew method of the GridViewListSource.
First, we will need to create a custom GridViewListSource:
public class MyGrid : RadGridView
{
protected override RadGridViewElement CreateGridViewElement()
{
return new MyGridViewElement();
}
}
public class MyGridViewElement : RadGridViewElement
{
protected override MasterGridViewTemplate CreateTemplate()
{
return new MyMasterGridViewTemplate();
}
protected override Type ThemeEffectiveType
{
get
{
return typeof(RadGridViewElement);
}
}
}
public class MyMasterGridViewTemplate : MasterGridViewTemplate
{
protected override GridViewListSource CreateListSource()
{
return new MyGridViewListSource(this);
}
}
public class MyGridViewListSource : GridViewListSource
{
private GridViewTemplate template;
public MyGridViewListSource(GridViewTemplate template)
: base(template)
{
this.template = template;
}
public override GridViewRowInfo AddNew()
{
GridObj gridObj = new GridObj();
IList list = (this as ICurrencyManagerProvider).CurrencyManager.List;
list.Add(gridObj);
IDataItem dataItem = (this.template as IDataItemSource).NewItem();
if (this.IsDataBound)
{
this.InitializeBoundRow((GridViewRowInfo)dataItem, gridObj);
}
return dataItem as GridViewRowInfo;
}
}
The GridObj type is a type, which implements the interface, which you have bound your RadGridView. Consider the following example:
public BindingToCollectionOfInterfaces()
{
InitializeComponent();
MyGrid grid = new MyGrid();
this.Controls.Add(grid);
grid.Dock = DockStyle.Fill;
IEnumerable<IGridObj> dataSource = new BindingList<IGridObj>();
grid.DataSource = dataSource;
grid.AllowAddNewRow = true;
}
public interface IGridObj
{
int Id { get; set; }
string Name { get; set; }
}
public class GridObj : IGridObj
{
public int Id { get; set; }
public string Name { get; set; }
public string RandomString { get; set; }
}
You will notice that we are creating a BindingList of IGridObject, because the new items are manually added and this way the grid will be notified for the new objects.