c# - 带有组合框的 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;
}
}
}
}
解决方案
你是对的; 看来 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 个约翰确实会选择那个,而不是第一个。