gpt4 book ai didi

c# - 设置 DisplayMember 后 DataGridViewComboBoxColumn 会发生什么情况?

转载 作者:太空宇宙 更新时间:2023-11-03 13:32:57 27 4
gpt4 key购买 nike

当我有一个 DataGridViewComboBoxColumn填充绑定(bind)值,如果我设置 DisplayMember属性,我得到 DataError使用 FormatException 引发的事件:

DataGridViewComboBoxCell value is not valid

如果 DisplayMember 未设置,因此 View 显示 .ToString() 的结果,所有工作均按预期进行。

这是一个完整的例子:

public partial class Form1 : Form
{
public Form1() { InitializeComponent(); }

private void Form1_Load(object sender, EventArgs e)
{
var categories = new[] { CustomerCategory.Cat1, CustomerCategory.Cat2, CustomerCategory.Cat3 };
this.dataGridView1.AutoGenerateColumns = false;
this.dataGridView1.DataError += new DataGridViewDataErrorEventHandler(dataGridView1_DataError);
this.dataGridView1.CellParsing += new DataGridViewCellParsingEventHandler(dataGridView1_CellParsing);
this.dataGridView1.Columns.Add(new DataGridViewComboBoxColumn()
{
DataSource = categories,
HeaderText = "Category",
DataPropertyName = "Category",
DisplayMember = "Name" // if we omit this line, there is not DataError event raised
});

this.dataGridView1.DataSource = new[]
{
new Customer() { Category = CustomerCategory.Cat1 }
, new Customer() { Category = CustomerCategory.Cat2 }
, new Customer() { Category = CustomerCategory.Cat3 }
}.ToList();
}

void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
var value = this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
var type = value != null ? value.GetType() : null;
string message = "Error"
+ Environment.NewLine + " - Column : " + e.ColumnIndex
+ Environment.NewLine + " - Line : " + e.RowIndex
+ Environment.NewLine + " - Value : " + Convert.ToString(value) + " (" + type + ")"
+ Environment.NewLine + " - Exception : " + e.Exception.Message;
Debug.Fail(message);
}

void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
//http://stackoverflow.com/questions/631126/how-to-bound-a-datagridviewcomboboxcolumn-to-a-object
if (this.dataGridView1.CurrentCell.OwningColumn is DataGridViewComboBoxColumn)
{
var editingControl = (DataGridViewComboBoxEditingControl)this.dataGridView1.EditingControl;
e.Value = editingControl.SelectedItem;
e.ParsingApplied = true;
}
}
}

模型:

public class CustomerCategory
{
public static readonly CustomerCategory Cat1 = new CustomerCategory { Name = "Cat1" };
public static readonly CustomerCategory Cat2 = new CustomerCategory { Name = "Cat2" };
public static readonly CustomerCategory Cat3 = new CustomerCategory { Name = "Cat3" };

public string Name { get; set; }
public override string ToString() { return this.Name; }
}
public class Customer { public CustomerCategory Category { get; set; } }

如何指定我自己的 DisplayMember 而不会引发这个烦人的 DataError 事件?
该问题仅出现在 DataGridViewComboBoxColumn 中,而不出现在常规 ComboBox 中。 .

编辑:经过几次测试,我可以这样说:

[DisplayMember + Not ValueMember] = FAIL
[Not DisplayMember + ValueMember] = FAIL
[DisplayMember + ValueMember] = WIN

所以我的问题可以改写为:是否有任何文档可以准确解释什么有效,什么无效?以及 DisplayMember + ValueMember 是如何链接在一起的?

重新编辑:

一个有趣的引用:Problems with the DataGridViewComboBoxColumn

However, the DataGridViewComboBoxColumn doesn't work like this, although it will display the ToString value if you don't set the DisplayMember, something internally goes wrong when it tries to look up the SelectedItem, you have to set DisplayMember to a public property of your class. Even worse, the default behaviour if you don't set the ValueMember property is to return the DisplayMember, there's no way of getting actual item itself. The only work around is to add a property to your class that returns itself and set that property to the ValueMember. Of course, if your item isn't something you are able to change (such as one of the framework classes) you'll have to cludge together a container object that holds a reference to your item.

是否有人有关于内部出现问题部分的任何信息?

最佳答案

以下逻辑可能会帮助您解决问题。

我认为问题出在代码行的顺序上。在分配显示成员属性后分配数据源可能会导致错误。

改变这一行;

this.dataGridView1.Columns.Add(new DataGridViewComboBoxColumn()
{
DataSource = categories,
HeaderText = "Category",
DataPropertyName = "Category",
DisplayMember = "Category" // if we omit this line, there is not DataError event raised
});

DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
col.HeaderText = "Category";
col.DataSource = categories;
col.DisplayMember = "Category";
col.DataPropertyName = "Category";
this.dataGridView1.Columns.Add(col);

数据源必须在 DisplayMember 和 ValueMember 之前赋值。

关于c# - 设置 DisplayMember 后 DataGridViewComboBoxColumn 会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19861381/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com