DataGridViewComboBoxCell: how to set the selected value when adding a row?

I have this form that allows the user to select an item (code - product) from comboxbox. enter quantity and price and add it to the list.

enter image description here

Loading inventory in the form

private List<Inventory> inventories = new Inventory().read_inventory(); 

Configuring ComboBox with Values

 private void set_drop_down_inventory() { cb_inventory.DisplayMember = "name"; cb_inventory.DataSource = inventories; cb_inventory.ResetText(); cb_inventory.SelectedIndex = -1; } 

When the user selects a product, he will create a new instance.

 private void cb_inventory_SelectionChangeCommitted(object sender, EventArgs e) { var selected_inventory = (cb_inventory.SelectedItem as Inventory); sales_order_detail = new Sales_Order_Detail(selected_inventory, 0); tx_description.Text = selected_inventory.description; tx_price.Text = selected_inventory.get_price_str(); } 

As soon as the user adds an item, he calls this code.

 private void btn_add_item_Click(object sender, EventArgs e) { // Set the inputted data into the instance before adding to the list sales_order_detail.description = tx_description.Text.ToString(); sales_order_detail.quantity = tx_quantity.Value; sales_order_detail.price = Convert.ToDecimal(tx_price.Text); // Adding the instances to a List sales_order.sales_order_details.Add(sales_order_detail); // Sets the Datagrid to provide the data+ initialize_datagrid(sales_order_detail); } 

This is how I initialize the datagrid because I need to manually display the columns - this is where I am not sure what to do - I believe that I do not need to manually add a new row every time the user adds an item because this datagrid is limited to List <>, so any instance is added to List <> it will be added to the grid when I run dgv.Refresh ()

 private void initialize_datagrid(Sales_Order_Detail sales_order_detail) { dgv_sales_order_details.Columns.Clear(); dgv_sales_order_details.DataSource = null; dgv_sales_order_details.Refresh(); dgv_sales_order_details.AutoGenerateColumns = false; // Set the datasource to the list where the item is added dgv_sales_order_details.DataSource = sales_order.sales_order_details; DataGridViewComboBoxColumn product_code_col = new DataGridViewComboBoxColumn(); DataGridViewColumn description_col = new DataGridViewColumn(); DataGridViewColumn quantity_col = new DataGridViewColumn(); DataGridViewColumn price_col = new DataGridViewColumn(); DataGridViewColumn account_col = new DataGridViewColumn(); DataGridViewComboBoxCell product_cell = new DataGridViewComboBoxCell(); DataGridViewTextBoxCell description_cell = new DataGridViewTextBoxCell(); DataGridViewTextBoxCell amount_cell = new DataGridViewTextBoxCell(); product_cell.DisplayMember = "name"; // They have the same Datasource as the combobox above. product_cell.DataSource = inventories; product_code_col.CellTemplate = product_cell; product_code_col.DataPropertyName = nameof(sales_order_detail.inventory.name); //This binds the value to your column product_code_col.HeaderText = "Code"; product_code_col.Name = "name"; description_col.CellTemplate = description_cell; description_col.DataPropertyName = nameof(sales_order_detail.description); description_col.HeaderText = "Description"; description_col.Name = "description"; quantity_col.CellTemplate = amount_cell; quantity_col.DataPropertyName = nameof(sales_order_detail.quantity); quantity_col.HeaderText = "Quantity"; quantity_col.Name = "quantity"; quantity_col.DefaultCellStyle.Format = "0.00"; quantity_col.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; price_col.CellTemplate = amount_cell; price_col.DataPropertyName = nameof(sales_order_detail.price); price_col.HeaderText = "Price"; price_col.Name = "price"; price_col.DefaultCellStyle.Format = "0.00"; price_col.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; dgv_sales_order_details.Columns.Add(product_code_col); dgv_sales_order_details.Columns.Add(description_col); dgv_sales_order_details.Columns.Add(quantity_col); dgv_sales_order_details.Columns.Add(price_col); dgv_sales_order_details.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; } 

This is the result when the item is added, but since you can see that the combobox column does not display the value, it only displays the value when I click the combobox column. and when I change the value in the dropdown above the list, the value in the combobox column also changes. they seem to be attached.

enter image description here

My goal is to add a row to the datagrid where the comboboxcolumn displays what I have selected and fix the duplicate combo box selection.

Please comment if this requires clarification so that I can fix it. Thanks!

+5
source share
2 answers

I managed to solve it, this is my decision. This is the best solution that I have come up with so far. Please comment if you have any corrections. so we could improve it. Hope this helps others too.

  • Created a DataGridView handler so that I can reuse it in other forms and add additional conditions for its flexibility.

     namespace Project.Classes { public static class DGV_Handler { public static DataGridViewComboBoxColumn CreateInventoryComboBox() { DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn(); // This lets the combo box display the data selected // I set the datasource with new instance because if i use the Datasource used in the combobox in the item selection. the combobox in the grid and that combox will be binded. if i change one combobox the other one follows. combo.DataSource = new Inventory().read_inventory(); combo.DataPropertyName = "inventory_id"; combo.DisplayMember = "name"; combo.ValueMember = "inventory_id"; combo.Name = "inventory_id"; combo.HeaderText = "Code"; combo.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft; return combo; } public static DataGridViewComboBoxColumn CreateGLAccountComboBox() { DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn(); combo.DataSource = new Account().read(); combo.DataPropertyName = "gl_account_sales"; combo.DisplayMember = "account_name"; combo.ValueMember = "account_id"; combo.Name = "account_id"; combo.HeaderText = "Account"; combo.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft; return combo; } public static DataGridViewTextBoxColumn CreateTextBox(string dataproperty, string headertext, string name, bool is_numbers) { DataGridViewTextBoxColumn textbox = new DataGridViewTextBoxColumn(); textbox.DataPropertyName = dataproperty; textbox.HeaderText = headertext; textbox.Name = name; if (is_numbers) { textbox.DefaultCellStyle.Format = "0.00"; textbox.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; } return textbox; } } } 
  • When the form is loaded, I initialize the datagrid as follows.

     private void initialize_datagrid() { dgv_sales_order_details.Columns.Clear(); dgv_sales_order_details.Refresh(); dgv_sales_order_details.AutoGenerateColumns = false; dgv_sales_order_details.DataSource = bindingSource1; dgv_sales_order_details.Columns.Add(DGV_Handler.CreateInventoryComboBox()); dgv_sales_order_details.Columns.Add(DGV_Handler.CreateTextBox("description","Description", "description", false)); dgv_sales_order_details.Columns.Add(DGV_Handler.CreateTextBox("quantity","Quantity","quantity", true)); dgv_sales_order_details.Columns.Add(DGV_Handler.CreateTextBox("price", "Price", "price", true)); dgv_sales_order_details.Columns.Add(DGV_Handler.CreateGLAccountComboBox()); dgv_sales_order_details.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; dgv_sales_order_details.RowHeadersVisible = false; dgv_sales_order_details.EditMode = DataGridViewEditMode.EditOnEnter; } 
  • Code when adding a new line

     private void btn_add_item_Click(object sender, EventArgs e) { if(validate_selection()) { // Set the properties to be included in the DGV Column var selected_row = (cb_inventory.SelectedValue as Inventory); var selected_gl_account = (cb_gl_account.SelectedValue as Account); string description = tx_description.Text; decimal quantity = tx_quantity.Value; decimal price = Convert.ToDecimal(tx_price.Text); int gl_account_id = selected_gl_account.account_id; // When something new is added to the bindingsource, the DGV will be refresh bindingSource1.Add(new Sales_Order_Detail(selected_row, description, quantity, price, 0, gl_account_id)); clear_item_selection(); } } 

Result

enter image description here

+1
source
 DataGridViewComboBoxColumn c = new DataGridViewComboBoxColumn(); c.Name = "ComboColumn"; c.DataSource = dataTable; c.ValueMember = "ID"; c.DisplayMember = "Item"; dataGridView1.Columns.Add(c); 

To select a specific value, you set the Value property for this cell.

 dataGridView1.Rows[rowIndexYouWant].Cells["ComboColumn"].Value = 1; 

Please note that this type is important! IF , you say you get a System.FormatException . This may be caused by setting the wrong type to value.

When you set the value to 1, you assign int - if for some reason you have rows in the ID column, you will get a System.FormatException exception that you see.

If the types are different, you need to either update the DataTable definition or set a value for the string:

 dataGridView1.Rows[rowIndexYouWant].Cells["ComboColumn"].Value = "1"; 

to add lines you may need

 dataGridView1.Rows.Add(); int z=0; for (int a = 0; a < dataGridView1.comlumncount; a++) { dataGridView1.Rows[z].Cells[a].Value = "yourvalue"; z++; } 

For reference, check the Link , you can solve your problem.

+1
source

Source: https://habr.com/ru/post/1264230/


All Articles