How to display field values of two classes in a DataGridView? [duplicate]

1

I'm populating a DataGridView object with a list of classes of type List<Curso> , and the way that I populate DataGridView is as follows:

meuDataGridView.DataSource = cursos;

However, one of the fields in my class Curso is another class, which in this case is the Instituicao class. And in the data view in the grid the Nome field of the Instituicao class does not appear correctly.

Here is an illustration of the data on the grid:

Reproducingtheminimumexample

Inordertoreproducetheminimalexampleoftheproblem,youwillneedtheclassCursoofclassInstituicaoandaformwithDataGridView.

ClassCourse:

classCurso{publicstringDescricao{get;set;}publicintCargaHoraria{get;set;}publicInstituicaoInstituicao{get;set;}}

InstitutionClass:

publicclassInstituicao{publicstringNome{get;set;}}

FormclasswithDataGridViewanddatapopulatedinit:

publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidForm1_Load(objectsender,EventArgse){varcursos=newList<Curso>{newCurso{Descricao="Curso Java",
                CargaHoraria = 99999999,
                Instituicao = new Instituicao
                {
                    Nome = "Instituicao Javali"
                }

            },
            new Curso
            {
                Descricao = "Curso Python",
                CargaHoraria = 1,
                Instituicao = new Instituicao
                {
                    Nome = "Monty Python"
                }
            },
            new Curso
            {
                Descricao = "Curso de PHP",
                CargaHoraria = -99999999,
                Instituicao = new Instituicao
                {
                    Nome = "Instituicao no fim da galaxia"
                }
            }
        };

        PopulaGrid(cursos);
    }

    private void PopulaGrid(List<Curso> cursos)
    {
        if (cursos != null && cursos.Any())
        {
            dataGridView.DataSource = cursos;
        }
    }
}

Question

How can I display the value of the property Nome of class Instituicao on the grid instead of that unusual value?

    
asked by anonymous 13.07.2018 / 17:02

2 answers

2

You can use several forms:

Anonymous object:

dataGridView1.DataSource = cursos.Select(x=> new { Descrição = x.Descricao, Instituição = x.Instituicao.Nome  }).ToList();

Add a property in Courses that returns only the Name of the Institution:

public class Curso
{
    public string Descricao { get; set; }
    public int CargaHoraria { get; set; }
    public Instituicao Instituicao { get; set; }

    public string InstituicaoNome => this.Instituicao.Nome;
}

Override ToString method, but only applicable to a property:

public class Instituicao
{
    public string Nome { get; set; }

    public override string ToString()
    {
        return this.Nome;
    }
}

Or, format the value during the CellFormating event of the DataGridView:

private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    DataGridViewColumn column = dataGridView1.Columns[e.ColumnIndex];
    if (column.DataPropertyName.Contains("."))
    {
        object data = dataGridView1.Rows[e.RowIndex].DataBoundItem;
        string[] properties = column.DataPropertyName.Split('.');
        for (int i = 0; i < properties.Length && data != null; i++)
            data = data.GetType().GetProperty(properties[i]).GetValue(data);
        dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = data;
    }
}

The latter, I find the most costly, and has been removed from SOen: link

  

Not directly linked but related: How to get the value of a property with Expression

    
13.07.2018 / 17:31
2

As your Institution class has only one property, the appropriate one would perhaps be to put it in course. But it depends on how you want to use it later. Other solutions would give an override on ToString by printing the name of the institution:

public class Instituicao
{
    public string Nome { get; set; }

    public override string ToString()
    {
        return Nome;
    }
}

Or create an anonymous object with the complete data:

private void PopulaGrid(List<Curso> cursos)
{
    if (cursos != null && cursos.Any())
    {
        dataGridView1.DataSource = cursos.Select(c => new { c.CargaHoraria, c.Descricao, Instituição = c.Instituicao.Nome }).ToList();
    }
}
    
13.07.2018 / 17:22