简体   繁体   English

如何将 DataGridViewComboBoxColumn 绑定到 object?

[英]How to bound a DataGridViewComboBoxColumn to a object?

I'm trying to bound a DataGridViewComboBoxColumn to an instance of Foo, but when i set a value on the grid i got a ArgumentException telling me that i can not convert from String to Foo.我正在尝试将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

Am i missing something?我错过了什么吗? is it possible to databind to a complex object?是否可以将数据绑定到复杂的 object?

UPDATE:更新:

I implemented a TypeConverter and overrided CanConvertFrom, CanConvertTo, ConvertTo, ConvertFrom.我实现了一个 TypeConverter 并覆盖了 CanConvertFrom、CanConvertTo、ConvertTo、ConvertFrom。 Now i'm getting现在我得到

FormatException: The DataGridViewComboBoxCell value is not valid FormatException:DataGridViewComboBoxCell 值无效

Any ideas?有任何想法吗?

You are missing a possible piece.你错过了一个可能的部分。

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;

UPDATE:更新:

Actually, after reading your question again, I think you are facing that noted bug.实际上,在再次阅读您的问题后,我认为您正面临着那个注意到的错误。 There is unfortunately no way to make it return the bound object without using a custom TypeDescriptor/TypeConverter/BindingSource.不幸的是,如果不使用自定义 TypeDescriptor/TypeConverter/BindingSource,就无法让它返回绑定的 object。

Answer for binding to a complex object.绑定到复杂的 object 的答案。 No by default.默认没有。 I wrote quite a nice one for my current project.我为我当前的项目写了一个相当不错的。 This involves making a custom TypeDescriptor/TypeConverter/BindingSource that returns all the nested properties.这涉及制作一个返回所有嵌套属性的自定义 TypeDescriptor/TypeConverter/BindingSource。 Another 'bug', you cant use '.'另一个“错误”,您不能使用“。” for a member separator, I had to resort to ':' instead.对于成员分隔符,我不得不求助于“:”。

the DataGridViewComboBoxColumn should always have all the possible values at the combobox Items list or it will throw "FormatException: The DataGridViewComboBoxCell value is not valid". DataGridViewComboBoxColumn 应始终具有 combobox 项目列表中的所有可能值,否则它将抛出“FormatException:DataGridViewComboBoxCell 值无效”。

If you are trying to get back values chosen from one combobox column, you can handle the DataGridView CellParsing event, and get the selected item from DataGridView.EditingControl cause it will be set for editing control from the edited column.如果您试图取回从 combobox 列中选择的值,您可以处理 DataGridView CellParsing 事件,并从 DataGridView.EditingControl 获取选定项,因为它将设置为从已编辑列进行编辑控制。 Here is a exemple:这是一个例子:

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;
   }
}

You also can customize the way your objects are show on each cell by handling the cell Formatting Event, here is a code that display toString for any object or interface.您还可以通过处理单元格格式事件来自定义对象在每个单元格上的显示方式,这里是显示任何 object 或接口的 toString 的代码。

private void dataGridView1_CellFormatting(object sender, 
    DataGridViewCellFormattingEventArgs e) {
        if (e.Value != null) {
            e.Value = e.Value.ToString();
            e.FormattingApplied = true;
        }
    } 

Handles this two events should be enough for show and edit data within any bussiness object and its easer then write type converters.处理这两个事件应该足以显示和编辑任何业务 object 及其轻松然后编写类型转换器中的数据。 For this work set you DataGridView and you combobox column as follow:对于这项工作,您可以设置 DataGridView 和 combobox 列,如下所示:

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 ();

No DisplayMember or ValueMember Property need to be set, just make sure your combobox data source list has all the possible values for Foo.无需设置 DisplayMember 或 ValueMember 属性,只需确保您的 combobox 数据源列表具有 Foo 的所有可能值。

Hope its helps.希望它有所帮助。

Actually, you can use a complex type in DataGridViewComboBoxColumn .实际上,您可以在DataGridViewComboBoxColumn中使用复杂类型。

For example:例如:

DataGridViewComboBoxColumn.DataPropertyName = "ValueMode";
DataGridViewComboBoxColumn.DisplayMember = "Label";
DataGridViewComboBoxColumn.ValueMember = "Self"; *
DataGridViewComboBoxColumn.ValueType = typeof(ValueModeItem);

Self is: Self是:

public ValueModeItem Self
{
    get
    {
        return this;
    }
}

Very important - need to override 'Equals' method of a complex type.非常重要 - 需要覆盖复杂类型的 'Equals' 方法。 In my case:就我而言:

public override bool Equals(object obj)
{
    if (obj is ValueModeItem && obj != null)
    {
        if (...)
            return true;
    }
    return false;
}

I was constantely hitting the same problem until I discovert that you cannot set the DisplayMember of the DataGridViewComboBoxCell without setting the ValueMember too.我一直在遇到同样的问题,直到我发现如果不设置ValueMember就无法设置DataGridViewComboBoxCellDisplayMember
In the same way, setting the ValueMember and not the DisplayMember is a fail too, you have to define none or both.同样,设置ValueMember而不是DisplayMember也是失败的,您必须定义 none 或两者都定义。

Your model is Foo, and you certainly want that the Value of the ComboBox be the item itself.您的 model 是 Foo,您当然希望 ComboBox 的值是项目本身。 For doing this, the simplest way is too create a Property in your foo, returning itself.为此,最简单的方法是在您的 foo 中创建一个属性,然后返回自身。

public class Foo
{
    ...
    public Foo This { get {return this; } }
}

Then bindings becomes:然后绑定变为:

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
column.ValueMember = "This";

This should work, and the Value of the Cell should be of type Foo as expected.这应该可以工作,并且单元格的值应该是 Foo 类型,如预期的那样。

An interesting reference: Problems with the DataGridViewComboBoxColumn一个有趣的参考: 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.但是,DataGridViewComboBoxColumn 不是这样工作的,尽管如果您不设置 DisplayMember,它将显示 ToString 值,但当它尝试查找 SelectedItem 时出现内部问题,您必须将 DisplayMember 设置为的公共属性你的 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.更糟糕的是,如果您不设置 ValueMember 属性,则默认行为是返回 DisplayMember,无法获取实际项目本身。 The only work around is to add a property to your class that returns itself and set that property to the ValueMember.唯一的解决方法是向 class 添加一个属性,该属性返回自身并将该属性设置为 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.当然,如果您的项目不是您能够更改的东西(例如框架类之一),您将不得不将一个包含对您的项目的引用的容器 object 聚集在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将DataGridViewComboBoxColumn绑定到父行的绑定对象的list属性? - How do I bind a DataGridViewComboBoxColumn to the list property of the parent row's bound object? 绑定网格的DataGridViewComboboxColumn - DataGridViewComboboxColumn for Bound Grid 绑定到DataTable的DataGridViewComboBoxColumn上的DataError - DataError on DataGridViewComboBoxColumn bound to a DataTable 将DataGridViewColumn更改为绑定DataGridView中的DataGridViewComboBoxColumn - Change DataGridViewColumn to DataGridViewComboBoxColumn in bound DataGridView 如何将DataGridViewComboBoxColumn绑定到返回列表的对象的属性/方法? - How do I bind a DataGridViewComboBoxColumn to a property/method of an object that returns a list? 如何在不使用对象的情况下检查DataGridViewComboBoxColumn中的项? - How can I check for an item in a DataGridViewComboBoxColumn without using an object? 无法将 DataGridViewComboBoxColumn 中的值设置为绑定的 DataGridView - Cannot set values from a DataGridViewComboBoxColumn to a bound DataGridView 如何将DataGridViewComboboxColumn添加到Datagrid - How to add DataGridViewComboboxColumn to a Datagrid 如何填充DataGridViewComboBoxColumn - How to populate the DataGridViewComboBoxColumn 如何在 DataGridViewComboBoxColumn 中设置 SelectedIndex? - how to set SelectedIndex in DataGridViewComboBoxColumn?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM