Reputation: 569
I have a datagrid view that I need to populate with content from the database. My database content is in a datatable that typically looks like this :
Prod id ProdName Version
1 abc 1.1
1 abc 2.1
1 abc 3.1
2 def 3.1
2 def 3.2
3 ghi 1.1
4 jkl 1.1
4 jkl 1.2
Now my problem is that when i display the content in a datagrid view, I want it to be displayed as such, where version should be a dropdown comboboxcell so each product has a list of versions :
Prod id ProdName Version
1 abc 1.1
2.1
3.1
2 def 3.1
3.2
3 ghi 1.1
4 jkl 1.1
1.2
Please help me in achieving this. I cannot directly say :
dataGridView1.DataSource = getdatatable()
So please do not suggest that as it gives me a flat view with no combobox. Eagerly looking forward to a positive reply. Is it possible to draw each row in the datagrid view and populate the combobox in that row with all the versions available for a product ? Please help. TIA
Upvotes: 0
Views: 463
Reputation: 5454
Essentially, you need to sort through your queried data, saving each unique product with a list of all its versions. Then you would manually create the columns for your DataGridView as I'll describe below.
To mock out this scenario I created the following object class:
// The type of binding object for your dgview source.
public class Product
{
public Product()
{
this.Version = new List<double>();
}
public int ID { get; set; }
public string Name { get; set; }
public List<double> Version { get; set; }
}
In your query returning all the objects, I would do something like this:
public BindingList<Product> YourQueryCall()
{
BindingList<Product> products = new BindingList<Product>();
/*
* Your code to query the db.
*/
while reader.Read()
{
Product existingProduct = new Product();
int id = // value from the reader
string name = // value from the reader
double version = // value from the reader
try
{
existingProduct = products.Single(p => p.ID == id && p.Name == name);
existingProduct.Version.Add(version);
}
catch // No product yet exists for this id and name.
{
existingProduct.ID = id;
existingProduct.Name = name;
existingProduct.Version.Add(version);
products.Add(existingProduct);
}
}
return products;
}
That will store only unique products and their lists of versions. And in the form, to show each row's unique list of versions in a ComboBoxColumn:
public Form1()
{
InitializeComponent();
this.Products = YourQueryCall();
this.FillDGView();
}
public BindingList<Product> Products { get; set; }
public void FillDGView()
{
DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
col1.Name = "Product ID";
col1.ValueType = typeof(int);
dataGridView1.Columns.Add(col1);
DataGridViewTextBoxColumn col2 = new DataGridViewTextBoxColumn();
col2.Name = "Product Name";
col2.ValueType = typeof(string);
dataGridView1.Columns.Add(col2);
DataGridViewComboBoxColumn col3 = new DataGridViewComboBoxColumn();
col3.Name = "Version";
col3.ValueType = typeof(double);
dataGridView1.Columns.Add(col3);
for (int i = 0; i < this.Products.Count; i++)
{
DataGridViewRow row = (DataGridViewRow)(dataGridView1.Rows[0].Clone());
DataGridViewTextBoxCell textCell = (DataGridViewTextBoxCell)(row.Cells[0]);
textCell.ValueType = typeof(int);
textCell.Value = this.Products[i].ID;
textCell = (DataGridViewTextBoxCell)(row.Cells[1]);
textCell.ValueType = typeof(string);
textCell.Value = this.Products[i].Name;
DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)(row.Cells[2]);
comboCell.ValueType = typeof(double);
comboCell.DataSource = this.Products[i].Version;
comboCell.Value = this.Products[i].Version[0];
dataGridView1.Rows.Add(row);
}
}
Hope this helps!
Upvotes: 3