2017-02-15 130 views
5

我有这种表单让用户从comboxbox中选择一个(代码 - 产品)项目。输入数量和价格并将其添加到列表中。DataGridViewComboBoxCell:如何在添加行时设置选定的值?

enter image description here

加载库存的形式

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

与设定值

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

} 

这是我的初始化数据网格,因为我需要手动显示的列 - 这是我不知道该怎么做 - 我相信我并不需要手动添加一个新行每次因为这个数据网格为界列表<>,所以无论实例添加到列表<>它将被添加到网格时,我触发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; 
} 

这是用户将商品添加项目时的结果,但您可以看到组合框列未显示值,它仅显示当我单击公司时的值mbobox列。当我更改列表上方的组合框中的值时,组合框列中的值也会更改。看起来他们被绑住了。

enter image description here

我的目标是能够添加一行到DataGrid其中comboboxcolumn显示什么,我选择和修正,以组合框中选择复制。

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

回答

1

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

  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. 当窗体被加载时,我像这样初始化datagrid。

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

结果

enter image description here

+0

我upvoted为可重用的datagrid处理程序。 – Binsoi

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

要选择特定值,请设置给定单元格的Value属性。

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

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

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

如果类型不同,你需要更新该数据表的定义或将值设置为一个字符串:

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你可能会解决你的问题

+0

嗨的时候,感谢您的回答。我将尝试使用这些工作 –

+0

这可以在我添加一行时起作用,但是当我添加另一行时,现有行将不再显示选定的值。 –

+0

已更新链接回答让我知道它是否没有为你工作 – Dandy

相关问题