首页 > 解决方案 > 带有组合框的 Datagridview 引用自己的数据集混合行

问题描述

我有一个 DataGridView,它基于 BindingSource 引用的数据库中的 DataSet。在 DataSet 中有一个 ID 作为主键。此外,DataSet 中还有另一个字段,其中包含一个 BuddyID 引用同一表的另一行。以及一个包含元素名称的字段。

在 DataGridView 中有名为 DataGridViewTextboxColumn 的名称和 DataGridViewComboboxColumn ,您可以在其中选择另一个元素的名称来更改 BuddyID,由另一个 BindingSource 引用到相同的 DataSet。但这不像我想要的那样工作。

当您有两个元素作为彼此的好友并且您想要设置 ID 时,另一个元素的 BuddyID 也会更改为相同的值。虽然我没有改变其他 ComboBox 的价值正在改变!也许这是组合框的问题,但我不知道该怎么做才能解决这个问题。也许你的任何人?

编辑:两个(伙伴)元素具有相同的名称出现在组合框中

设计师生成的代码 - 不幸的是名称为“text”而不是“combo”:

    private System.Windows.Forms.DataGridViewComboBoxColumn idBuddyDataGridViewTextBoxColumn;

    private System.Windows.Forms.DataGridViewComboBoxColumn idB uddyDataGridViewTextBoxColumn;

      // 
      // idBuddyDataGridViewTextBoxColumn
      // 
      this.idBuddyDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
      this.idBuddyDataGridViewTextBoxColumn.DataPropertyName = "IdBuddy";
      this.idBuddyDataGridViewTextBoxColumn.DataSource = this.komponentenBuddyBindingSource;
      this.idBuddyDataGridViewTextBoxColumn.DisplayMember = "Komponentenname";
      this.idBuddyDataGridViewTextBoxColumn.HeaderText = "Buddy";
      this.idBuddyDataGridViewTextBoxColumn.Name = "idBuddyDataGridViewTextBoxColumn";
      this.idBuddyDataGridViewTextBoxColumn.Resizable = System.Windows.Forms.DataGridViewTriState.True;
      this.idBuddyDataGridViewTextBoxColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
      this.idBuddyDataGridViewTextBoxColumn.ValueMember = "Id";
      this.idBuddyDataGridViewTextBoxColumn.Width = 62;

设计人员为 DataGridView 编写的代码:

private System.Windows.Forms.DataGridView dgvKomponenten;
  this.dgvKomponenten = new System.Windows.Forms.DataGridView();
  ((System.ComponentModel.ISupportInitialize)(this.dgvKomponenten)).BeginInit();

  // 
  // dgvKomponenten
  // 
  this.dgvKomponenten.AllowUserToDeleteRows = false;
  this.dgvKomponenten.AutoGenerateColumns = false;
  this.dgvKomponenten.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
  this.dgvKomponenten.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
        this.komponentennameDataGridViewTextBoxColumn,
        ... (10 other columns) ...
        this.idBuddyDataGridViewTextBoxColumn});
  this.dgvKomponenten.DataSource = this.komponentenBindingSource;
  this.dgvKomponenten.Dock = System.Windows.Forms.DockStyle.Fill;
  this.dgvKomponenten.Location = new System.Drawing.Point(0, 0);
  this.dgvKomponenten.Name = "dgvKomponenten";
  this.dgvKomponenten.Size = new System.Drawing.Size(452, 612);
  this.dgvKomponenten.TabIndex = 9;
  this.dgvKomponenten.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvKomponenten_CellValueChanged);
  this.dgvKomponenten.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(this.dgvKomponenten_DataError);
  this.dgvKomponenten.RowEnter += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvKomponenten_RowEnter);
  ((System.ComponentModel.ISupportInitialize)(this.dgvKomponenten)).EndInit();

还有一些我自己调用的代码:

private void dgvKomponenten_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
  DataGridView dgvChanged = ((DataGridView)sender);
  FilteredTypeDataGridViewComboBoxCell ftdgvcbcSubtyp;

  if (null != dgvChanged.Columns["idTypDataGridViewTextBoxColumn"])
  {
    if (e.ColumnIndex == dgvChanged.Columns["idTypDataGridViewTextBoxColumn"].Index)
    {
      ftdgvcbcSubtyp = (FilteredTypeDataGridViewComboBoxCell)dgvChanged.Rows[e.RowIndex].Cells["idSubtypDataGridViewTextBoxColumn"];
      ftdgvcbcSubtyp.InitCellFilter(e.RowIndex);
      if (!ftdgvcbcSubtyp.Items.Contains(ftdgvcbcSubtyp.Value))
      {
        ftdgvcbcSubtyp.Value = 0;
      }
    }
  }

}

标签: c#.netdatabasedatagridviewcomboboxcolumn

解决方案


你是对的; 看来 DGV 中使用的组合有一个错误,它会根据显示文本不区分大小写地查找所选项目。如果您有5,"John"甚至5,"john"永远无法选择它,因为选择它总是会找到/将选择设置为第一个约翰(id 为 1 的那个)

这是我能想到的最好的解决方法:

    public class Buddy {
        public string Name { get; set; }
        public int Id { get; set; }
    }

    public Form1(string s1 = null)
    {
        InitializeComponent();

        dataSet1.People.AddPeopleRow(1, "John", 1);
        dataSet1.People.AddPeopleRow(2, "Mary", 1);
        dataSet1.People.AddPeopleRow(3, "Mark", 1);
        dataSet1.People.AddPeopleRow(4, "Luke", 1);
        dataSet1.People.AddPeopleRow(5, "John", 1);

        var b = new BindingList<Buddy>();
        var h = new Dictionary<string, int>();
        foreach (var r in dataSet1.People)
        {
            if (!d.TryGetValue(r.Name.ToLower(), out int x))
                x = 0;
            b.Add(new Buddy { Name = r.Name + (x > 0 ? new string('\0', x) : ""), Id = r.Id });
            d[r.Name.ToLower()] = x + 1;
        }

        buddyBindingSource.DataSource = b;
        peopleBindingSource.DataSource = dataSet1.People;

    }

即,我们通过构建新的名称/ID 对列表的人员列表进行压缩,以显示在我们的组合中。每次我们遇到以前见过的名字时,我们都会在名字的末尾添加越来越多的 NUL 字符。它们不会显示在组合中,但它们允许文本不同,因此选择第 5 个约翰确实会选择那个,而不是第一个。


推荐阅读