DataGridViewComboBoxCell:添加行时如何设置选定值?

DataGridViewComboBoxCell : How to set selected value when adding a row?

我有这个表单,允许用户从组合框中选择一个(代码 - 产品)项目。输入数量和价格并添加到列表中。

正在将库存加载到表单中

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

使用值设置 ComboBox

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

当用户选择一个产品时,它会创建一个新实例。

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();

 }

一旦用户添加项目,它就会触发此代码。

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);

}

这就是我初始化数据网格的方式,因为我需要手动显示列——这是我不确定该做什么的地方——我相信我不需要在每次用户添加时手动添加新行一个项目,因为这个数据网格绑定到 List<>,所以无论实例添加到 List<>,当我触发 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;
}

这是添加项目时的结果,但是您可以看到组合框列没有显示值,它仅在我单击组合框列时显示值。当我更改列表上方组合框中的值时,组合框列中的值也会更改。看来他们是绑定的。

我的目标是能够在组合框列显示我选择的内容的数据网格中添加一行,并修复组合框重复选择。

如果需要更多说明,请发表评论,以便我进行更正。谢谢!

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

要select一个特定值,您可以设置给定单元格的值属性。

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

注意这里的类型很重要! IF 你说你得到一个 System.FormatException。这可能是由于将错误的类型设置为值引起的。

当您将该值设置为 1 时,您正在分配一个 int - 如果出于某种原因您在 ID 列中有字符串,您将得到您所看到的 System.FormatException 异常。

如果类型不同,您需要更新 DataTable 定义或将值设置为字符串:

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

添加您可能需要的行

dataGridView1.Rows.Add();
int z=0;
 for (int a = 0; a < dataGridView1.comlumncount; a++)
         {

            dataGridView1.Rows[z].Cells[a].Value = "yourvalue";
            z++;
         }

供您参考检查此Link您可能会解决您的问题

我已经设法解决了,这是我的解决方案。这是迄今为止我提出的最佳解决方案。如果您有任何更正,请发表评论。所以我们可以改进它。我希望这也会对其他人有所帮助。

  1. 创建了一个 DataGridView 处理程序,这样我就可以在其他形式中重用它,并为它添加更多灵活的条件。

    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;
           }
    
       }
    }
    
  2. 加载表单后,我会像这样初始化数据网格。

    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;
    
    }
    
  3. 添加新行时的代码

    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();
        }
    }
    

结果