Search code examples
c#winformsdata-bindingdatagridviewbinding

Binding generic data to DataGridView


I am trying to create a generic DataGridView that can be generated based on a list of any data type. For that, I created a user control with generic type T, and when I am adding an instance of it to another form, I initialize it with the class I want the DataGridView to be populated. I also created a method that sets the generic table bindings, based on the data list that I feed it.

public partial class UCTabelaDinamica<T> : UserControl
{
    private BindingSource TableSource { get; set; }
    private BindingList<T> TableList { get; set; }

    public UCTabelaDinamica()
    {
        InitializeComponent();
    }

    public void SetTableBindings(IList<T> tableData)
    {
        TableList = new BindingList<T>(tableData);
        TableSource = new BindingSource(TableList, null);

        dtTabela.AutoGenerateColumns = true;
        dtTabela.DataSource = TableSource;
    }
}

Now, to use this user control in the form, I instantiate it like this:

private void InitializeComponent()
    {
        this.ucTabelaDinamica1 = new DataGridViewBuilderImproved.UCTabelaDinamica<Person>();
        this.SuspendLayout();
        // 
        // ucTabelaDinamica1
        // 
        this.ucTabelaDinamica1.Location = new System.Drawing.Point(12, 12);
        this.ucTabelaDinamica1.Name = "ucTabelaDinamica1";
        this.ucTabelaDinamica1.Size = new System.Drawing.Size(475, 337);
        this.ucTabelaDinamica1.TabIndex = 0;
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(499, 361);
        this.Controls.Add(this.ucTabelaDinamica1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

    }

    #endregion

    private UCTabelaDinamica<Person> ucTabelaDinamica1;

After that, I populate the table:

private void Form_Load(object sender, EventArgs e)
    {
        List<Person> people = new List<Person>
        {
            new Person
            {
                name = "Joao",
                age = 18
            },
            new Person
            {
                name = "Pedro",
                age = 21
            }
        };

        ucTabelaDinamica1.SetTableBindings(people);
    }

The problem is the table is showing in the form, but no data is showing, or columns are created, and I cannot understand why. I have searched and seen different topics about this, saying to use BindingList, and then BindingSource, but nothing seems to be working. Little help?

UPDATE:

As @Jimi suggested, I moved the generic T type to the SetTableBindings function, but it still doesn't show me any data in the table

public partial class UCTabelaDinamica : UserControl
{
    private BindingSource TableSource { get; set; }

    public UCTabelaDinamica()
    {
        InitializeComponent();
    }

    public void SetTableBindings<T>(IList<T> tableData)
    {
        TableSource = new BindingSource(new BindingList<T>(tableData), null);

        dtTabela.AutoGenerateColumns = true;
        dtTabela.DataSource = TableSource;
    }
}

Solution

  • I just figured out what was happening.

    My Person class had the following:

     public class Person
    {
        public string name;
        public int age;
    }
    

    I changed it to:

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    

    And it is now fully working.