将具有不同数据源的 DataGridViewComboBoxCell 添加到 DataGridView

Posted

技术标签:

【中文标题】将具有不同数据源的 DataGridViewComboBoxCell 添加到 DataGridView【英文标题】:Add DataGridViewComboBoxCell with different data sources to a DataGridView 【发布时间】:2013-11-07 02:57:01 【问题描述】:

我已经检查了其他帖子,但仍然无法修复我的问题: 我有两种形式:

创建客户(可以有多个电话、地址和汽车) 应该显示每个客户信息的主窗体。

首先,是否有可能在每一行中都有一个客户,以及每个客户信息的三个组合(电话、地址和汽车)?

例如:

我有两个客户,John 和 Jack,我希望这些行显示如下:

0 - John - John.Phones - John.Addresses - John.Cars 1 - Jack - Jack.Phones - Jack.Addresses - Jack.Cars

另外,我不知道我应该将什么作为组合框的参数传递给我的行,我应该传递数据源、项目还是组合本身?无论我为组合框传递什么,我都会得到: System.ArgumentException: DatagridViewRowComboBoxCell value is not valid

这是实际代码。

private DataGridViewRow BuildRow(Cliente cliente)

    DataGridViewRow row = new DataGridViewRow();           
    DataGridViewComboBoxCell Autos = new DataGridViewComboBoxCell();


    Autos.DataSource = cliente.Autos;
    Autos.ValueMember = cliente.Autos[0].ToString();
    row.CreateCells(DGCliente, cliente.Codigo.ToString(), cliente.Nombre, Autos);
    row.Tag = cliente;
    DGCliente.Rows.Add(row);

    return row;

客户端类代码:(西班牙语)

public class Cliente

    public String Nombre  get; set; 
    public Int32 Codigo  get; set; 
    public List<Auto> Autos  get; set; 
    public List<Direccion> Direcciones  get; set; 
    public List<Telefono> Telefonos  get; set; 

    public Cliente()
    
        this.Direcciones = new List<Direccion>();
        this.Telefonos = new List<Telefono>();
        this.Autos = new List<Auto>();

    

    public Cliente(String Nombre , Int32 Codigo)
    
        this.Nombre = Nombre;
        this.Codigo = Codigo;
        this.Direcciones = new List<Direccion>();
        this.Telefonos = new List<Telefono>();
        this.Autos = new List<Auto>();
    

    public void AgregarTelefono(bool esCelular, String numero, String area)
     
       this.Telefonos.Add(new Telefono(esCelular, numero, area));
    

    public void AgregarDireccion(string calle, string altura, string localidad, string provincia)
    
        this.Direcciones.Add(new Direccion(calle, altura, localidad, provincia));
    

    public void AgregarAuto(Auto auto)
    
        this.Autos.Add(auto);
    

【问题讨论】:

如果方法已经添加了行,为什么要返回该行(如果需要,反之亦然)?此外,缺少变量的命名。 Autos 是什么?您将其用作DataGridViewComboBoxCell (简称 DGVCBC)以及您的 Cliente 对象的属性?您可以发布客户代码吗? Autos 只是我想给我想添加到行中的组合的名称,我猜应该命名为 DGVCBCAutos 你应该有,确实:)。不管怎样,现在你给你的客户 ctor 打了两次电话,并添加了一些电话、地址和汽车,对吧?然后当你调用 buildrow 时,我假设它会崩溃。您可以发布初始化代码,还是来自数据库? (所以我可以在这里测试它)。 (为什么是 altura 而不是 numero 呢??) 【参考方案1】:

关于您的第一个问题。当然可以。您可以查看 here,或查看任何其他带有该标签的 ***。

真正的问题是如何。大多数帖子都与 WPF 相关,在这种情况下,绑定会有所帮助,但我强烈建议阅读 this guy's blog,其中他有一个示例,其中包含类似结果的代码。

苏尔特 :)

编辑: 您的DataGridViewComboBoxCell 源应该是IListIListSource,其中包含用于向下拉列表提供数据的值集合(如果您不相信我,请查看here)。

因此,您的每个对象都应该有一个属性,它是List 或任何您想要满足IList 接口的属性,并且您应该将它绑定到您的源。

因此,例如,如果以下类是您的对象,您应该将该对象绑定到该行,但特别是将 BindToThis1 (&2) 绑定到您的 DataGridViewComboBoxCell 源(就像他在示例中使用 dtTitles 所做的那样)。

public class MyObject

    public List<string> BindToThis1  get; set; 
    public List<string> BindToThis2  get; set; 

    public MyObject()
    
        BindToThis1 = new List<string>  "hello", "world" ;
        BindToThis2 = new List<string>  "red", "blue", "green" ;
    

【讨论】:

谢谢,但我的问题是我需要为不同的组合框提供不同的数据源,而博客中的示例只有一个,并且适用于整个专栏。另外我需要用我的客户数据创建一行,我不知道要传递什么参数。 我已经这样做了,客户端类有 3 个属性是集合,(列表 和 )仍然无法解决我的问题。【参考方案2】:

您可以为每个客户创建一行,其中包含两种类型的单元格:文本框单元格和组合框单元格。 考虑以下几点:

 public class PersonRow : DataGridViewRow
    
        public DataGridViewTextBoxCell Name;
        public DataGridViewComboBoxCell Phones;
        public DataGridViewComboBoxCell Cars;

        public PersonRow(Person person)
        
            Name.Value = person.Name;

            DataGridViewComboBoxCell phones = new DataGridViewComboBoxCell();
            phones.Items.AddRange((DataGridViewComboBoxCell.ObjectCollection)person.Phones); //add the items from Person.Phones to PersonRow.Phones combobox cell

            Phones = phones;

            DataGridViewComboBoxCell cars = new DataGridViewComboBoxCell();
            cars.Items.AddRange((DataGridViewComboBoxCell.ObjectCollection)person.Cars); //add Person.Cars to PersonRow.Cars combobox cell 

            Cars = cars;

            Cells.AddRange(new DataGridViewCell[]  Name, Phones, Cars ); //add cells to the row

        
    

public class Person
    
        public string Name  get; set; 

        public IList<Phones>  Phones  get; set;  //be sure to use the IList interface
        public IList<Cars> Cars  get; set;  //be sure to implement the IList interface

        public Person( string name, List<Phones> phones, List<Cars> cars)
        
            Name = name;
            Phones = phones;
            Cars = cars;
        
    

public class Phones
    
        public string Name  get; set; 
        public string Model  get; set; 

        public Phones(string name, string model)
        
            Name = name;
            Model = model;

        
    

    public class Cars
    
        public string Name  get; set; 
        public string Model  get; set; 

        public Cars(string name, string model)
        
            Name = name;
            Model = model;
        
    

也结帐:http://msdn.microsoft.com/en-us/library/bc3sctb6(v=vs.110).aspx 和http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.objectcollection.aspx 和http://msdn.microsoft.com/en-us/library/system.collections.ilist(v=vs.110).aspx 希望这会有所帮助!

【讨论】:

以上是关于将具有不同数据源的 DataGridViewComboBoxCell 添加到 DataGridView的主要内容,如果未能解决你的问题,请参考以下文章

将具有不同数据源的 DataGridViewComboBoxCell 添加到 DataGridView

将具有不同索引的数据框添加到时间序列

如何将原始数据插入具有不同列序列的配置单元表中?

如何将具有不同名称和相同架构的 Excel 文件导入数据库?

将数据库导入另一个具有不同名称的数据库

通过灵活的调用将具有不同宽度的数据从宽转向长(用于循环)