【问题标题】:Programmatically add cells and rows to DataGridView以编程方式将单元格和行添加到 DataGridView
【发布时间】:2014-10-16 13:53:08
【问题描述】:

我正在为DataGridViewComboBoxCell 苦苦挣扎。在某些情况下(比如事件),我必须在表单的DataGridView 中预先选择一个值ComboBox。当用户更改一个框时,我可以像这样以编程方式更改另一个框:

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

我正在像这样填充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));
}

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

效果很好,但是...

现在我想在表单加载时向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);
}

这会引发心爱的DataGridViewComboBox value is not valid 异常。请帮忙,我对此没有想法。我不想使用DataSource 或类似的东西。 ItemCode 和 ItemName 列项通过 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;
    }
}

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

ItemName.ValueMember = "Id";
ItemName.DisplayMember = "Name";
ItemCode.ValueMember = "Id";
ItemCode.DisplayMember = "Name";

【问题讨论】:

  • “我不想使用 DataSource 或类似的东西”是什么意思?如果您不设置它们,ComboBox 将如何知道要选择的项目?它只会知道当前选择的值。此外,请确保您手动添加的单元格与 DataGrid 列的顺序正确。
  • 我通过ItemName.Items.Add(...)将项目添加到ComboBox,其中ItemName是ComboBox。就像我说的那样,当我更改网格单元格更改的值时它会起作用,但当我在加载时以编程方式添加行时不起作用。
  • 好吧,我不知道是什么原因造成的。你发了很多sn-ps,但是很难把它们关联起来,而且我敢肯定其中有一半与问题无关。尝试创建short self contained example。从只有带有组合框列的数据网格的新项目开始,并在加载事件中添加虚拟项目。如果成功,则包含 cellchanged 事件。逐步增加代码并测试问题,直到它出现在最短的独立示例中。然后,您要么了解问题,要么至少查明问题,让其他人解决它。
  • 好吧,我会努力的……

标签: c# winforms datagridview datagridviewcombobox datagridviewcomboboxcell


【解决方案1】:

好的,我自己解决了。

显然,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);
}

【讨论】:

    【解决方案2】:
            DataGridViewColumn[] dgCol = 
            {
              new DataGridViewTextBoxColumn() 
              {
                  HeaderText = "Conviction", 
                  SortMode = DataGridViewColumnSortMode.NotSortable,
                  Width = Convert.ToInt32(0.25f * grdConvictions.Width - 19)
              },
              new DataGridViewTextBoxColumn() 
              {
                  HeaderText = "Points"    , 
                  SortMode = DataGridViewColumnSortMode.NotSortable,
                  Width = Convert.ToInt32(0.125f * grdConvictions.Width - 19)
              },
              new DataGridViewTextBoxColumn() 
              {
                  HeaderText = "Date", 
                  SortMode = DataGridViewColumnSortMode.NotSortable,
                  Width = Convert.ToInt32(0.125f * grdConvictions.Width - 19),
              },
              new DataGridViewComboBoxColumn () 
              {
    
                  HeaderText = "Galletas", 
                  Width = Convert.ToInt32(0.25 * grdConvictions.Width - 19),          
                  DataPropertyName  = "Galletas",
                  DataSource = new List<String>{"",
                                              "Maiz",
                                              "Pera",
                                              "Manzana",
                                              "Sandia",
                                              "Fresa",
                                              "Melon",
                                              "Melocoton",
                                              "Maracuya",
                                              "Cereza",
                                              "Frambuesa",
                                              "Mora",
                                              "Kiwi",
                                              "Anona",
                                              "Guayaba"
                                            },
                  SortMode = DataGridViewColumnSortMode.NotSortable,
                  MaxDropDownItems = 10,
    
                  DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing,
                  ReadOnly = false
              }
            };
    

    YourDataGridView.Columns.AddRange(dgCol);

    【讨论】:

      【解决方案3】:

      注意:DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox 才能看到组合。我用作“无”,并且...:

          private void grdConvictions_CellEnter(object sender, DataGridViewCellEventArgs e)
          {
              int colIndex = e.ColumnIndex;
              int rowIndex = e.RowIndex;
      
              if (rowIndex < 0 || colIndex < 0)
              {
                  return;
              }
      
              DataGridView grd = (DataGridView)sender;
      
              if (grd[e.ColumnIndex, e.RowIndex].GetType().Name != "DataGridViewComboBoxCell")
              {
                  ((DataGridViewComboBoxCell)grd.CurrentCell).DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
              }
      

      }

          private void grdConvictions_CellLeave(object sender, DataGridViewCellEventArgs e)
          {
              int colIndex = e.ColumnIndex;
              int rowIndex = e.RowIndex;
      
              if (rowIndex < 0 || colIndex < 0)
              {
                  return;
              }
      
              DataGridView grd = (DataGridView)sender;
      
              if (grd[e.ColumnIndex, e.RowIndex].GetType().Name != "DataGridViewComboBoxCell")
              {
                  ((DataGridViewComboBoxCell)grd.CurrentCell).DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
              }
      
          }
      

      【讨论】:

        猜你喜欢
        • 2015-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-23
        • 2020-10-18
        • 1970-01-01
        相关资源
        最近更新 更多