Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将DataGridViewComboBoxColumn绑定到对象?_C#_Winforms_Data Binding_Datagridview_Datagridviewcombobox - Fatal编程技术网

C# 如何将DataGridViewComboBoxColumn绑定到对象?

C# 如何将DataGridViewComboBoxColumn绑定到对象?,c#,winforms,data-binding,datagridview,datagridviewcombobox,C#,Winforms,Data Binding,Datagridview,Datagridviewcombobox,我试图将一个DataGridViewComboBoxColumn绑定到一个Foo实例,但是当我在网格上设置一个值时,我得到一个ArgumentException告诉我不能从字符串转换为Foo var data = (from item in someTable select new { Foo = item.foo, Bar = item.Bar }).ToList(); grid.DataSource = data; column.DataPropertyName =

我试图将一个
DataGridViewComboBoxColumn
绑定到一个Foo实例,但是当我在网格上设置一个值时,我得到一个
ArgumentException
告诉我不能从字符串转换为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:DataGridViewComboxCell值无效


有什么想法吗?

你错过了一个可能的片段

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;
更新:

事实上,在再次阅读您的问题之后,我认为您正面临着那个著名的bug。不幸的是,如果不使用自定义TypeDescriptor/TypeConverter/BindingSource,就无法让它返回绑定对象


回答绑定到复杂对象的问题。默认情况下没有。我为我当前的项目写了一篇很好的文章。这涉及到创建一个自定义TypeDescriptor/TypeConverter/BindingSource,返回所有嵌套属性。另一个“错误”,您不能使用“.”作为成员分隔符,我必须使用“:”。

DataGridViewComboBoxColumn应始终在combobox项列表中包含所有可能的值,否则它将抛出“FormatException:DataGridViewComboxCell值无效”

如果试图从一个组合框列中获取所选值,则可以处理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;
        }
    } 
处理这两个事件应该足以显示和编辑任何业务对象及其easer中的数据,然后写入类型转换器。对于此工作,请按如下方式设置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 ();
不需要设置DisplayMember或ValueMember属性,只需确保combobox数据源列表中包含所有可能的Foo值


希望能有所帮助。

我一直在遇到同样的问题,直到我发现如果不设置
ValueMember
也不能设置
DataGridViewComboxCell
DisplayMember

同样,设置
ValueMember
而不是
DisplayMember
也是失败的,您必须定义none或两者

您的模型是Foo,您当然希望ComboBox的值是项本身。要做到这一点,最简单的方法就是在foo中创建一个属性,并返回它自己

public class Foo
{
    ...
    public Foo This { get {return this; } }
}
然后绑定变成:

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";
这应该可以工作,并且单元格的值应该是预期的Foo类型

一个有趣的参考:

但是,DataGridViewComboBoxColumn不是这样工作的, 尽管如果不设置 DisplayMember,当它试图查看时,内部出现问题 在SelectedItem上,必须将DisplayMember设置为公共 您的类的属性。更糟糕的是,如果你不这样做,那就是默认行为 设置ValueMember属性是为了返回DisplayMember,有 无法获取实际项目本身。唯一的解决办法是添加一个 属性,并将该属性设置为 价值观成员。当然,如果你的物品不是你能做的 要更改(例如某个框架类),您必须使用clude 一个容器对象,其中包含对项目的引用


实际上,您可以在
datagridviewcomboxcolumn
中使用复杂类型

例如:

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

public ValueModeItem Self
{
    get
    {
        return this;
    }
}
非常重要-需要重写复杂类型的“Equals”方法。 就我而言:

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

如何创建TypeConverter?从TypeConverter继承并重写GetProperties/GetPropertiesSupported方法。然后将该类型应用于所需目标类型的TypeConverterAttribute。主题区域非常大。我实现了一个TypeConverter并覆盖了CanConvertTo、CanConvertFrom、ConvertTo和ConvertFrom,现在我得到了错误“FormatException:DataGridViewComboxCell的值无效”,在设置了值之后,有趣的是,这是唯一为我做这项工作的,同时也是最简单的。我看不出它怎么只得到4票,而且很难找到。你知道为什么默认实现会尝试
将所选项的字符串表示形式转换为数据源的类型(这对于自定义类型来说是失败的,并且很难用自定义转换器进行自定义),而不是像标准组合框那样设置所选项(可用!)??