我试图绑定一个DataGridViewComboBoxColumn
Foo的实例,但是当我在网格上设置一个值时,我得ArgumentException
知道我无法从String转换为Foo.
var data = (from item in someTable select new { Foo = item.foo, Bar = item.Bar }).ToList(); grid.DataSource = data; column.DataPropertyName = "Foo"; column.DataSource = (from foo in Foo select foo).ToList (); //foo is an instance of Foo column.DisplayMember = "SomeNameField"; //Foo.SomeNameField contains a description of the instance
我错过了什么吗?是否可以数据绑定到复杂的对象?
更新:
我实现了TypeConverter并覆盖了CanConvertFrom,CanConvertTo,ConvertTo,ConvertFrom.现在我来了
FormatException:DataGridViewComboBoxCell值无效
有任何想法吗?
你错过了一件可能的作品.
column.DataPropertyName = "Foo"; column.DisplayMember = "SomeNameField"; column.ValueMember = "Bar"; // must do this, empty string causes it to be // of type string, basically the display value // probably a bug in .NET column.DataSource = from foo in Foo select foo; grid.DataSource = data;
更新:
实际上,在再次阅读你的问题之后,我认为你正面临着那个着名的错误.遗憾的是,如果不使用自定义TypeDescriptor/TypeConverter/BindingSource,则无法返回绑定对象.
回答绑定到复杂对象.没有默认值.我为我当前的项目写了一篇很好的文章.这涉及制作一个返回所有嵌套属性的自定义TypeDescriptor/TypeConverter/BindingSource.另一个'错误',你不能使用'.' 对于成员分隔符,我不得不求助于':'.
DataGridViewComboBoxColumn应始终具有组合框列表中的所有可能值,否则将抛出"FormatException:DataGridViewComboBoxCell值无效".
如果您尝试从一个组合框列中选择值,则可以处理DataGridView CellParsing事件,并从DataGridView.EditingControl获取所选项,因为它将被设置为从编辑列中进行编辑控制.这是一个例子:
private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e) { if (dataGridView1.CurrentCell.OwningColumn is DataGridViewComboBoxColumn) { DataGridViewComboBoxEditingControl editingControl = (DataGridViewComboBoxEditingControl)dataGridView1.EditingControl; e.Value = editingControl.SelectedItem; e.ParsingApplied = true; } }
您还可以通过处理单元格格式化事件来自定义对象在每个单元格上显示的方式,这是一个显示任何对象或接口的toString的代码.
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (e.Value != null) { e.Value = e.Value.ToString(); e.FormattingApplied = true; } }
处理这两个事件应该足以在任何商业对象中显示和编辑数据,然后更容易编写类型转换器.为此工作设置DataGridView和您的组合框列如下:
var data = (from item in someTable select new { Foo = item.foo, Bar = item.Bar }).ToList(); grid.DataSource = data; column.DataPropertyName = "Foo"; column.DataSource = (from foo in Foo select foo).ToList ();
不需要设置DisplayMember或ValueMember属性,只需确保您的组合框数据源列表具有Foo的所有可能值.
希望它的帮助.
实际上,您可以在中使用复杂类型DataGridViewComboBoxColumn
。
例如:
DataGridViewComboBoxColumn.DataPropertyName = "ValueMode"; DataGridViewComboBoxColumn.DisplayMember = "Label"; DataGridViewComboBoxColumn.ValueMember = "Self"; * DataGridViewComboBoxColumn.ValueType = typeof(ValueModeItem);
Self
是:
public ValueModeItem Self { get { return this; } }
非常重要-需要覆盖复杂类型的“等于”方法。就我而言:
public override bool Equals(object obj) { if (obj is ValueModeItem && obj != null) { if (...) return true; } return false; }