为什么我不能成功地将 DataGridviewColumnCollection 绑定到 ComboBox.DataSource 并指定 Display/ValueMember?

Why can't I successfully bind a DataGridviewColumnCollection to a ComboBox.DataSource and specify a Display/ValueMember?

在尝试绑定组合以便用户可以从下拉列表中 select 列名称并从 SelectedValue 检索列索引时,我注意到组合似乎忽略了给定的 DisplayMember 和ValueMember 而不是使用 ToString()

转载:

    

public Form1()
{
    InitializeComponent();

    var dt = new DataTable();
    dt.Columns.Add("A");
    dt.Columns.Add("B");
    dataGridView1.DataSource = dt;

    comboBox1.DisplayMember = nameof(DataGridViewColumn.Name);
    comboBox1.ValueMember = nameof(DataGridViewColumn.Index);
    comboBox1.DataSource = dataGridView1.Columns;
}

image of form - please embed

如果调换项目顺序:

comboBox1.DataSource = dataGridView1.Columns;
comboBox1.DisplayMember = nameof(DataGridViewColumn.Name);
comboBox1.ValueMember = nameof(DataGridViewColumn.Index);

C# 抱怨无法设置 DisplayMember。我更加困惑,因为:

调整集合类型也不会产生任何不同的结果:

comboBox1.DataSource = dataGridView1.Columns.Cast<DataGridViewColumn>().ToList();

问题似乎与尝试绑定的 DataGridViewColumn class 有关。如果列集合被投影到具有相同属性名称的匿名类型,它可以正常工作:

comboBox1.DataSource = dataGridView1.Columns.Cast<DataGridViewColumn>().Select(c => new { c.Name, c.ColumnIndex }).ToList();

我很好奇为什么 DataGridViewColumn,显然是一个 class 和 public 命名的 props 像其他任何东西一样,在这个绑定场景中不能直接工作

这是因为这些属性不可浏览。

DataGridViewColumn class 没有什么特别之处,即使是自定义创建的 class 行为也是一样的。这些属性(名称和索引)被标记为 [Browsable(false)],并且在设置数据绑定时,CurrencyManager.GetItemProperties 只是 returns 可浏览的属性。

如果您从 ValueMember, you will end up in some internal methods 开始跟踪代码,检查可浏览的属性。

最好的解决方法是您还提到的方法,将结果调整为自定义类型:

comboBox1.DataSource = dataGridView1.Columns.Cast<DataGridViewColumn>()
    .Select(c => new { c.Name, c.ColumnIndex }).ToList();
comboBox1.ValueMember = "Index";
comboBox1.DisplayMember = "Name";