Neha
Neha

Reputation: 569

Datagridview Data Population from the database where one cell is a combobox c#

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

Answers (1)

OhBeWise
OhBeWise

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

Related Questions