当使用绑定值填充DataGridViewComboBoxColumn
时,如果设置DisplayMember
属性,则使用FormatException
引发DataError
事件。
DataGridViewComboBoxCell值无效
如果没有设置DisplayMember
,并且视图显示的是.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
是如何像看起来那样连接在一起的?
重新编辑:
一个有趣的参考:DataGridViewComboBoxColumn存在的问题
但是,DataGridViewComboBoxColumn不像这样工作,尽管如果不设置DisplayMember,它将显示DisplayMember值,但是当它试图查找SelectedItem时,内部会出错,因此必须将DisplayMember设置为类的公共属性。更糟糕的是,如果不设置ValueMember属性,则默认行为是返回DisplayMember,因此无法获得实际项本身。惟一的方法是向类中添加一个属性,该属性返回自身并将该属性设置为ValueMember。当然,如果您无法更改项(例如框架类之一),则必须将包含对项的引用的容器对象集中在一起。
有人有任何关于的信息吗?--内部出了什么问题,部件?
发布于 2014-02-26 08:15:56
下面的逻辑可以帮助您解决问题。
我认为问题在代码行的顺序上。在“赋值显示成员”属性之后分配数据源可能会导致错误。
改变这条线;
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之前分配数据源。
https://stackoverflow.com/questions/19861381
复制相似问题