如何以编程方式设置DataGridViewComboBoxCell的值?

4

我在设置DataGridViewComboBoxCell的值时遇到了问题。虽然datagridview列与选择/值绑定,但当我尝试使用指定的comboBoxCells列值进行dgv.Rows.Add OR单独设置单元格的值时,它会生成“DataGridViewComboBoxCell value is not valid”错误。如果我添加一个具有这些列的空白值的行,则选项在组合框中正常显示。

我有一个对话框,该对话框传递了一个简单对象NDCRecord的arraylist。

public class NDCRecord
    {        
        public string NDCcode = "";
        public string UnitQuantity = "";
        public string UnitOfMeasurement = "";
        public string Type = "";
        public string Number = ""; 
    }

在对话框中,通过编程方式创建了一个数据网格,然后进行了重新填充。
public NationalDrugCodesForm(ref ArrayList ndcRecordsIn)
        {
            InitializeComponent();

            ndcRecords = ndcRecordsIn;            
            SetupDataGridViewColumns();
            PopulateForm();
        }

设置:

private void SetupDataGridViewColumns()
        {

            // -----------------------------------------------------
            // Add/Del column
            // -----------------------------------------------------
            DataGridViewButtonColumn dgvbcAddRemove = new DataGridViewButtonColumn();
            dgvbcAddRemove.HeaderText = "Add";
            dgvbcAddRemove.Text = "Add";
            dgvbcAddRemove.Name = "Add";

            DataGridViewCellStyle addButtonStyle = new DataGridViewCellStyle();
            addButtonStyle.BackColor = Color.Blue;
            addButtonStyle.ForeColor = Color.White;
            dgvbcAddRemove.HeaderCell.Style = addButtonStyle;

            dgvNDC.Columns.Add(dgvbcAddRemove);

            // -----------------------------------------------------
            // Additional Columns
            // -----------------------------------------------------
            dgvNDC.Columns.Add("NDCCode", "NDC Code");

            dgvNDC.Columns.Add("UnitQuantity", "Unit Quantity");

            DataGridViewComboBoxColumn unitOfMeasurement = new DataGridViewComboBoxColumn();
            unitOfMeasurement.HeaderText = "Unit Of Measurement";
            unitOfMeasurement.Name = "UnitOfMeasurement";
            dgvNDC.Columns.Add(unitOfMeasurement);

            DataGridViewComboBoxColumn type = new DataGridViewComboBoxColumn();
            type.HeaderText = "Type";
            type.Name = "Type";
            dgvNDC.Columns.Add(type);

            dgvNDC.Columns.Add("Number", "Prescription Number");

            AddLine("Del", "", "", "", "", "");

            BindUnitOfMeasurement((DataGridViewComboBoxCell)dgvNDC.Rows[0].Cells["UnitOfMeasurement"]);
            BindType((DataGridViewComboBoxCell)dgvNDC.Rows[0].Cells["Type"]);            
        }

The AddLine function:

    private void AddLine(string buttonLabel, string ndcCode, string unitQuantity, string unitOfMeasurement, string type, string rxNumber)
    {
        dgvNDC.Rows.Add(new object[] { buttonLabel, ndcCode, unitQuantity, unitOfMeasurement, type, rxNumber });
    }

绑定函数:
    private void BindUnitOfMeasurement(DataGridViewComboBoxCell cb)
    {
        string[] Values = { "F2", "GR", "ME", "ML", "UN" };
        string[] Choices = { "F2 - International Unit", "GR - Gram", "ME - Milligram", "ML - Milliliter", "UN - Unit" };

        ControlManip.DataBindDDL(cb, Choices, Values);
    }

    private void BindType(DataGridViewComboBoxCell cb)
    {
        string[] Values = { "XZ", "VY" };
        string[] Choices = { "XZ - Prescription Number", "VY - Link Sequence Number" };

        ControlManip.DataBindDDL(cb, Choices, Values);
        cb.Value = "XZ";
    }
public static void DataBindDDL(ref ComboBox cb, string[] Choices, string[] Values)
    {
      DataTable dt = new DataTable();

      dt.Columns.Add("Choice");
      dt.Columns.Add("Value");

      if (Choices.Length != Values.Length)
      {
        throw new Exception("Number of Choices and Values do not match!");
      }
      else
      {
        dt.Rows.Add(new object[] { "", "" });
        for (int i = 0; i < Choices.Length; i++)
        {
          if (Choices[i] is object && Values[i] is object)
          {
            dt.Rows.Add(new object[] { Choices[i], Values[i] });
          }
        }

        cb.DataSource = dt;
        cb.DisplayMember = "Choice";
        cb.ValueMember = "Value";
      }
    }

填写表格:

    private void PopulateForm()
    {
        if (ndcRecords == null || ndcRecords.Count == 0)
            return;

        dgvNDC.Rows.Clear();

        foreach(NDCRecord record in ndcRecords)
        {
            AddLine("Del", record.NDCcode, record.UnitQuantity, record.UnitOfMeasurement, record.Type, record.Number);
        }
    }

为了简化...我设置了一个带有组合框列的数据网格,并将这些列绑定到数据源。当添加具有这些列的空值行时,一切看起来都很好;组合框有应该有的选择。如果我尝试添加指定值的行,并且它们是组合框值的有效选择,则会出现错误。我在调试中注意到单元格没有“项”,这似乎是个问题...但是不理解,因为在未设置值时选择是存在的。 - 333Matt
请注意,在绑定方法中,ValueMember和DisplayMember是在CELL上设置的。我已经在COLUMN上设置了ValueMember、DisplayMember和DataPropertyName...但仍然得到相同的结果。 - 333Matt
1个回答

0
问题是我绑定了单个的单元格,而不是包含下拉框的列。我在点击"添加"按钮时插入了绑定方法,使得即使添加一行空值,下拉框仍然会填充数据。但是如果指定了值来添加一行,会出现错误,因为该行的下拉框列还没有任何内容。所以以下是代码的重要修改部分:
在SetupDataGridViewColumns方法中,将原来的绑定代码:
    BindUnitOfMeasurement((DataGridViewComboBoxCell)dgvNDC.Rows[0].Cells["UnitOfMeasurement"]);
BindType((DataGridViewComboBoxCell)dgvNDC.Rows[0].Cells["Type"]);   

使用

BindUnitOfMeasurement((DataGridViewComboBoxColumn)dgvNDC.Columns["UnitOfMeasurement"]);
BindType((DataGridViewComboBoxColumn)dgvNDC.Columns["Type"]);

并相应地修改绑定方法。然后,您可以添加一个带有空值或指定值的行,它将起作用(下面其中一个具有指定默认值,另一个留空供用户选择)

AddLine("Del", "", "", "", "XZ", "");

另外,我不确定这是否必要,但在实验过程中,我还为每个组合框列添加了以下内容:

type.ValueType = typeof (string);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接