Since you are using an IDictionary, the default binding mechanism will not be able to retrieve the individual entries nor the properties on the class AClass. You can create a custom BindingSource to handle these tasks.
The primary responsibility of custom BingSource is to supply a collection of ProperyDescriptors for the AClass type. These are retrieved using the TypeDescriptor.GetProperties Method. The BindingSource also needs to access the underlying DataSource items by index; this is handled in the indexer of the BindingSource.
To use this BindingSource, create an instance of it passing your IDictionary instance and then assign this BindingSource to the DataGridView's DataSource property.
internal class myBindingSource : BindingSource
{
private IDictionary<string, AClass> source;
private System.ComponentModel.PropertyDescriptorCollection props;
public myBindingSource(IDictionary<string, AClass> source)
{
this.source = source;
props = System.ComponentModel.TypeDescriptor.GetProperties(typeof(AClass));
this.DataSource = source;
}
public override System.ComponentModel.PropertyDescriptorCollection GetItemProperties(System.ComponentModel.PropertyDescriptor[] listAccessors)
{
return props;
}
public override object this[int index]
{
get {return this.source.Values.ElementAtOrDefault(index);}
set {}
}
public override bool AllowNew
{
get { return false; }
set{}
}
public override bool AllowEdit
{
get { return false; }
}
public override bool AllowRemove
{
get {return false;}
}
public override int Count
{
get {return ((this.source == null) ? -1 : this.source.Count);}
}
}
Edit: I have added an override of the Count property to the code to allow the the BindingSource.ResetBindings Method to work properly when called to force the bound control to re-read the values from the BindingSource. I have also updated the indexer code.
If you modify the custom BindingSource's underlying DataSource after assigning it as the DataGridView's DataSource, you will need to call the BindingSource.ResetBindings method for those changes to be reflected in the grid.
For Example:
private IDictionary<string, AClass> aList;
private myBindingSource bs;
public Form1()
{
InitializeComponent();
aList = new Dictionary<string, AClass>();
bs = new myBindingSource(aList);
dgv.DataSource = bs;
aList.Add("1", new AClass());
aList.Add("2", new AClass { data1 = "AA", data2 = "BB" });
bs.ResetBindings(false);
}