带有引用自己的数据集混合行的组合框的 Datagridview

Datagridview with comboboxes referencing to the own dataset mixing rows

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

在 DataGridView 中有名称为 DataGridViewTextboxColumn 的 DataGridViewComboboxColumn,您可以在其中 select 另一个元素的名称来更改 BuddyID,由另一个 BindingSource 尊重同一个数据集。但这并不像我希望的那样有效。

当你有两个元素作为彼此的好友并且你想设置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;
      }
    }
  }

}

你是对的;看来 DGV 中使用的组合有一个错误,它会根据显示文本不区分大小写地查找所选项目。如果你有 5,"John" 甚至 5,"john",你永远不能 select它,因为选择它总是 finds/sets select第一个约翰(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('[=10=]', x) : ""), Id = r.Id });
            d[r.Name.ToLower()] = x + 1;
        }

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

    }

即,我们快速浏览人员列表,构建 name/id 对的新列表以显示在我们的组合中。每次我们点击一​​个我们以前见过的名字时,我们都会在名字的末尾添加越来越多的 NUL 字符。它们不显示在组合中,但它们允许文本不同,因此 selecting the 5th John 确实 select 那一个,而不是第一个。