以编程方式将单元格和行添加到DataGridView

YOh*_*han 6 c# datagridview datagridviewcombobox winforms datagridviewcomboboxcell

我正在努力DataGridViewComboBoxCell.在某些情况下(比方说,事件)我必须ComboBox在我的表格中预先选择一个值DataGridView.当用户更改一个框时,我可以以编程方式更改另一个框:

var item = ItemName.Items.GetListItem(name);
if (item != null)
{
    _loading = true; // that's needed to come around another CellValueChanged events
    itemView.Rows[e.RowIndex].Cells["ItemName"].Value = item;
    _loading = false;
}
Run Code Online (Sandbox Code Playgroud)

我这样填充ItemName.Items:

foreach (var item in _model.DefaultData.ItemList)
{
    if (item.Value.Code.HasValue()) ItemCode.Items.Add(new ListItem(item.Key, item.Value.Code));
    ItemName.Items.Add(new ListItem(item.Key, item.Value.Name));
}
Run Code Online (Sandbox Code Playgroud)

GetListItem方法:

public static ListItem GetListItem(this DataGridViewComboBoxCell.ObjectCollection col, string name)
{
    ListItem retItem = null;
    foreach (ListItem item in col)
    {
        if (item.Name == name) { retItem = item; break; }
    }
    return retItem;
}
Run Code Online (Sandbox Code Playgroud)

这工作正常, ......

现在我想DataGridView在表单加载上添加行,如下所示:

foreach (var item in _model.SelectedItems)
{
    var row = new DataGridViewRow();
    row.Cells.Add(new DataGridViewTextBoxCell { Value = item.Id });
    row.Cells.Add(new DataGridViewComboBoxCell { Value = ItemCode.Items.GetListItem(item.Code) });
    row.Cells.Add(new DataGridViewComboBoxCell { Value = ItemName.Items.GetListItem(item.Name) });
    row.Cells.Add(new DataGridViewTextBoxCell { Value = item.Units });
    ...
    itemView.Rows.Add(row);
}
Run Code Online (Sandbox Code Playgroud)

并且引发了心爱的DataGridViewComboBox value is not valid异常.请帮忙,我对此不以为然.我不想使用DataSource或类似的东西.ItemCodeItemName列项目已填充并正确返回GetListItem().我不明白为什么它正常工作,但在表单加载它不起作用(显示它也不起作用).

编辑:对不起,忘了添加.

我的ListItem类:

public class ListItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ListItem(int sid, string sname)
    {
        Id = sid;
        Name = sname;
    }
    public override string ToString()
    {
        return Name;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经把它放在表单加载上了:

ItemName.ValueMember = "Id";
ItemName.DisplayMember = "Name";
ItemCode.ValueMember = "Id";
ItemCode.DisplayMember = "Name";
Run Code Online (Sandbox Code Playgroud)

YOh*_*han 6

好吧,我自己解决了。

显然,它不足以DataGridViewComboBoxColumn.Items容纳可能的物品。DataGridViewComboBoxCell.Items如果您要以编程方式添加新行,则还必须添加项目。

因此,如果其他人尝试使用我的没有数据绑定等的方法DataTable,这是我的解决方案:

foreach (var item in _model.SelectedItems)
{
    var row = new DataGridViewRow();
    var codeCell = new DataGridViewComboBoxCell();
    codeCell.Items.AddRange(ItemCode.Items);
    codeCell.Value = ItemCode.Items.GetListItem(item.Code);
    var nameCell = new DataGridViewComboBoxCell();
    nameCell.Items.AddRange(ItemName.Items);
    nameCell.Value = ItemName.Items.GetListItem(item.Name);
    row.Cells.Add(new DataGridViewTextBoxCell { Value = item.Id });
    row.Cells.Add(codeCell);
    row.Cells.Add(nameCell);
    row.Cells.Add(new DataGridViewTextBoxCell { Value = item.Units });
    row.Cells.Add(new DataGridViewTextBoxCell { Value = item.Quantity });
    row.Cells.Add(new DataGridViewTextBoxCell { Value = item.PriceLt });
    row.Cells.Add(new DataGridViewTextBoxCell { Value = item.PriceEu });
    itemView.Rows.Add(row);
}
Run Code Online (Sandbox Code Playgroud)