A WinForms DataGridView control has the ability to automatically generate its columns and populate from a specified data source (which can be a DataSet, a simple list or something else). All you have to do is something like this:
var list = new List<Record>() {new Record() {Id = 1, Name = "item 1", Date = DateTime.Now}}; this.dataGridView.AutoGenerateColumns = true; this.dataGridView.DataSource = list;
When you do the same in MFC, it doesn’t work (supposing that you followed all the steps for hosting a WinForms control in an MFC application as described in MSDN).
m_dgv->AutoGenerateColumns = true; auto source = gcnew System::Collections::Generic::List<Record^>(); auto r1 = gcnew Record(); r1->Id = 1; r1->Name = "item 1"; r1->Date = System::DateTime::Now; source->Add(r1); m_dgv->DataSource = source;
After debugging through the .NET framework sources I realized the problem was that the BindingContext property of the DataGridView control was null. This property represents a manager of the list of bindings for the control. If this is null then the control will use the binding context of the parent, which is usually a WinForms form. However, in this MFC application there is no WinForms form and the parent of the DataGridView control is null, which means the control does not have a bindings manager, and no bindings can be set.
The solution is to explicitly set the BindingsContext property to an existing binding context (a new object) before setting the data source.
m_dgv->BindingContext = gcnew System::Windows::Forms::BindingContext(); m_dgv->DataSource = source;
The lesson learned is that when you host a WinForms control in an MFC application some things won’t just work out of the box, if they rely on a parent form functionality. There is no such WinForms form and you might need to do additional manual initialization.
Thank you very much for publishing this solution. You have saved me from a very depressing problem – where the .NET controls worked perfectly in a .NET test program but failed in the MFC host.
Thank you also for the lesson learned, which I have taken to heart.