Binding a DataGridView to a class
-
Friday, August 10, 2012 11:07 AM
I have DataGridView and a container object. The containing object has some properties which are displayed for each object in DataGridView rows. One of these properties is a list of phone numbers stored as strings. I am unable to make DataGridViewComboBoxColumn show this property.
It should get the list of strings for each row and fill the list box but it isn't working.
- Moved by CoolDadTxMVP Friday, August 10, 2012 3:14 PM Winforms related (From:Visual C# General)
All Replies
-
Friday, August 10, 2012 11:26 AM
Hi,
Can you provide a piece of code or something? What does your DataGridViewComboBoxColumn show?
Thanks
-
Friday, August 10, 2012 11:57 AM
In DataRowBound assign data source to the combobox in the gridview column.. I suppose that you are trying to show a list of records and in each record you have a column that list down the phone numbers
If the phone numbers could be same you can do it one that is applicable for each row.
If the list different for the each record - assign data source to the combobox or add items - which ever suits to your data design/structure
-
Saturday, August 11, 2012 8:15 PM
public class Corp { public string corpName; public DateTime contractStartDate; public DateTime contractEndDate; public decimal contractValue; public List<Payment> payments; public List<Task> tasks; public string postalAddress; public List<PString> telnums; public Corp(string name, DateTime contractStartingDate, DateTime contractEndingDate, decimal _contractValue, string corpPostalAddress, List<PString> telNumbers ) { corpName = name; contractStartDate = contractStartingDate; contractEndDate = contractEndingDate; postalAddress = corpPostalAddress; contractValue = _contractValue; telnums = telNumbers; payments = new List<Payment>(); tasks = new List<Task>(); } public Corp() { payments = new List<Payment>(); tasks = new List<Task>(); } public string CorpName { get { return corpName; } set { corpName = value; } } public string ContractStartDate { get { return contractStartDate.ToShortDateString(); } set { contractStartDate = DateTime.Parse(value); } } public string ContractEndDate { get { return contractEndDate.ToShortDateString(); } set { contractEndDate = DateTime.Parse(value); } } public bool HasUndoneJob { get { if (tasks == null) return false; foreach (Task t in tasks) { if (!t.isDone) return true; } return false; } } public List<PString> TelNums { get { return telnums; } } public decimal CorpDebt { get { decimal debt = contractValue; foreach (Payment p in payments) debt -= p.amount; return debt; } } }And the container
public class Corps : System.ComponentModel.BindingList<Corp> { //public void AddCorp(); //public void RemoveCorp(); //public void ChangeCorp(); }
My DataGridView has a row for each corp and the problem is phone numbers that are not displayed. -
Thursday, August 16, 2012 10:21 AMModerator
Hi siavoshkc2,
You can create an unbound ComboBoxColumn in the DataGridView, and then set the DataSource property to bind the column to the bindingsource of the TelNums property. If TelNums is a list of string, that will be well. If you are using you own type, you have to set the DisplayMember and ValueMember property to the DataGridViewComboBoxColumn.
If there are any questions, please feel free to let me know.
Best regards,
Chester Hong
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
Thursday, August 16, 2012 4:30 PM
In the form designer when I first created the DataGridView I bound it to Corps. Then I set each column for each property. I had a property that returned a List<string> for phone numbers. I expected to see this property in the list of selectable properties as data source for ComboBoxColumn (As it is usual for a combo list to be filled with more than one string) but it wasn't the case and only the string property was shown. . This is where the problem started. Then I created a PString class that had a property which could return a string. But now that I think I see I was just so exhausted otherwise I could see that it wouldn't work because the binding source have to be the corps class otherwise rows can not extract data from each containing object.
Thank you.
- Edited by siavoshkc2 Thursday, August 16, 2012 4:31 PM
-
Friday, August 17, 2012 8:21 AMModerator
Hi siavoshkc2,
I think maybe you don't have the right binding source for the TelNum.
Suggest the datagridview's DataSource is set to corpBindingSource of the Corp class.
corpBindingSource.DataSource = typeof(MyProject.Corp);
After create a new combobox column, we can set the column's datasource property to a new bindingsource whose datasource is corpBindingSource:
this.telNumsBindingSource.DataSource = this.corpBindingSource; this.telNumsBindingSource.DataMember = "TelNums";
I have upload a demo project using VS2010 to skydrive. In fact I add all the columns of the datagridview in "Edit Columns" page, not by coding. You can have a look to see whether it works:
Chester Hong
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
- Marked As Answer by Chester HongMicrosoft Contingent Staff, Moderator Tuesday, September 04, 2012 9:16 AM
-
Sunday, August 19, 2012 9:20 AM
Thank you very much for the sample which works fine. I made my project like the sample with List<string> property being used only. But the list is not filled and remains empty. Can't find the difference between yours and my project.
The only difference is that I fill my table from Corps which inherits from BindingSource.
this.corpsBindingSource.DataSource = typeof(IranGostarAutomation.Corps); // // telNumsBindingSource // this.telNumsBindingSource.DataMember = "TelNums"; this.telNumsBindingSource.DataSource = this.corpsBindingSource;
- Edited by siavoshkc2 Sunday, August 19, 2012 5:57 PM
-
Monday, August 20, 2012 10:55 AMModerator
Hi siavoshkc2,
Yes, it seems that there is not difference with the code snippet you provided.
The only difference is that I fill my table from Corps which inherits from BindingSource.
Could you please provide some code snippet to show how do you fill the data? I would like to know if the data has been added correctly.
Best regards,
Chester Hong
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
Monday, August 20, 2012 1:05 PM
private void MainForm_Load(object sender, EventArgs e) { todayTxtBx.Text = DateTime.Today.ToShortDateString(); corpsDataGridView.DataSource = corps; List<string> ts = new List<string>(); ts.Add("234234"); ts.Add("3434"); corps.Add(new Corp("Ysdf", DateTime.Now, DateTime.Now, 456546, "ds", ts)); corpsDataGridView.Update(); }I also have a form thats fills the class in a similar method.
When the form loads I can see a new row for the Corp I added but the TelNum combo box is not filled.
I created a break point in TelNums property which returns List<string> and realized it is never being called.
And this how and where I selected data source for combo box column.
Which in turn creates telNumsBindingSource automatically. -
Tuesday, August 21, 2012 7:01 PM
I think I found the problem.
First of all if you uncheck Enable Editing for DataGridView, you won't be able to see the drop down list although it is Read-Only (design flaw?). Normally if you check it again you will be able to open the drop down list.
Now here is the important part:
If you change HeaderText to a Persian string (as you see in the picture I've sent before) and then uncheck Enable Editing and after that check it again, you won't be able to see the drop down list ever, even if you change HeaderText back to what it was. I don't know a way to repair it. It maybe a bug in the designer.
Here is my system info:
Microsoft Visual Studio 2010
Version 10.0.40219.1 SP1Rel
Microsoft .NET Framework
Version 4.0.30319 SP1RelInstalled Version: Professional
Microsoft Office Developer Tools
Microsoft Visual Basic 2010
Microsoft Visual C# 2010
Microsoft Visual C++ 2010
Microsoft Visual F# 2010
Microsoft Visual Studio 2010 Team Explorer
Microsoft Visual Web Developer 2010
Crystal Reports Templates for Microsoft Visual Studio 2010
Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2522890) KB2522890
Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2529927) KB2529927
Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2548139) KB2548139
Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2549864) KB2549864
Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2565057) KB2565057
Hotfix for Microsoft Visual Studio 2010 Professional - ENU (KB2635973) KB2635973
Microsoft Visual Studio 2010 Professional - ENU Service Pack 1 (KB983509) KB983509
Microsoft Visual Studio 2010 SharePoint Developer Tools 10.0.40219
Security Update for Microsoft Visual Studio 2010 Professional - ENU (KB2645410) KB2645410
Qt Add-in 1.1.9-1
For more information about the Qt Add-in, see
http://qt.nokia.com/
Copyright (c) 2008-2011 Nokia Corporation and/or its subsidiary(-ies)VMDebugger
For more information about VMware Inc, see their website at
http://www.vmware.com
Copyright (c) 2010 VMware, Inc.On Windows 7 64bit Version 6.1.7601 Service Pack 1 Build 7601
Application was built in x86-32bit mode
-
Wednesday, August 22, 2012 6:01 PMBeside my last post. I discovered an error in my code about giving the source instance of Corps to DGV. Look, I have a Corps class. I set my DataGridView to use it as the data source. But Corps is a data type. DGV should read data from one instance of Corps. From what I understood that instace is the BindingSource instance created by the designer. But what if I want to fill corps in another module? What if I want to use other methods of Corps (not the ones that are inherited from BindingSource)? What if I want to give DGV another instance as data source?
-
Sunday, August 26, 2012 2:13 PMShould I start a new thread for my last question?
-
Monday, August 27, 2012 6:27 AMModerator
Hi siavoshkc2,
Sorry for late response.
I have tried to create a Corps class. It seems that the reason is that you have changed the DataSource of the datagridview.
You can still use the corpsBindingSource as the datagridview's DataSource. But one thing to do is to set the corpsBindingSource's DataSource to the corps instance in the form's Load event:
private void MainForm_Load(object sender, EventArgs e) { todayTxtBx.Text = DateTime.Today.ToShortDateString(); //corpsDataGridView.DataSource = corps; corpsDataGridView.DataSource = corpsBindingSource; corpsBindingSource.DataSource = corps; ... }Best regards,
Chester Hong
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
- Edited by Chester HongMicrosoft Contingent Staff, Moderator Monday, August 27, 2012 6:32 AM
- Marked As Answer by Chester HongMicrosoft Contingent Staff, Moderator Tuesday, September 04, 2012 9:17 AM


