Fill Data Grid View with property of objects

8

I have a form where I need to fill a DataGridView with the data of a list of users. To generate this data, I used 3 classes:

User Class

namespace TesteDataGridView
{
    public class Usuario
    {
        public int id { get; set; }
        public string login { get; set; }
        public string nome { get; set; }
        public Perfil perfil { get; set; }

        public Usuario()
        {
            //Cada usuario que eu crio obrigatoriamente já cria seu perfil
            perfil = new Perfil();
        }
    }
} 

User List Class

using System.Collections.Generic;

namespace TesteDataGridView
{
    public class ListaUsuarios : List<Usuario>
    {
    }
}

Profile Class

namespace TesteDataGridView
{
    public class Perfil
    {
        public int id { get; set; }
        public string descricao { get; set; }
    }
}

Form File:

using System;
using System.Windows.Forms;

namespace TesteDataGridView
{
    public partial class Form1 : Form
    {
        ListaUsuarios lstUsr; //Cria uma lista de usuários

        public Form1()
        {
            InitializeComponent();

            //Instancia a lista de usuários
            lstUsr = new ListaUsuarios();

            //Não habilita a geração a
            dgv.AutoGenerateColumns = false;
        }

        private void btnCriaListaUsuarios_Click(object sender, EventArgs e)
        {
            //cria alguns usuários e adiciona na lista
            Usuario u1 = new Usuario();
            u1.id = 1;
            u1.login = "usr1";
            u1.nome = "usuario1";
            u1.perfil.id = 3;
            u1.perfil.descricao = "operador";

            lstUsr.Add(u1);

            Usuario u2 = new Usuario();
            u2.id = 2;
            u2.login = "usr2";
            u2.nome = "usuario2";
            u2.perfil.id = 2;
            u2.perfil.descricao = "lider";

            lstUsr.Add(u2);

            Usuario u3 = new Usuario();
            u3.id = 3;
            u3.login = "usr3";
            u3.nome = "usuario3";
            u3.perfil.id = 1;
            u3.perfil.descricao = "administrador";

            lstUsr.Add(u3);
        }

        private void btnPreencheGrid_Click(object sender, EventArgs e)
        {
            dgv.DataSource = null; //Limpa o grid;
            dgv.DataSource = lstUsr;
            dgv.Refresh();
        }
    }
}

In my DataGridView , in the DataPropertyName property, I set the column names and what to display in them as follows:

Column1 -  ID do Usuário     => DataPropertyName: id;
Column2 -  Nome do Usuário   => DataPropertyName: nome;
Column3 -  Login do Usuário  => DataPropertyName: login;
Column4 -  Perfil do Usuário => DataPropertyName: perfil.descricao;

With the first 3 columns, that's fine, but the profile column is not populated leaving my datagridview like this:

IfoundasolutionwheretheytalkedaboutoverrideinthetoStringmethodoftheProfileclassandsettheDataPropertyNameofcolumn4to"profile", but I did not find it very cool,

namespace TesteDataGridView
{
    public class Perfil
    {
        public int id { get; set; }
        public string descricao { get; set; }

        // Solução encontrada, fazer um override no método ToString()
        // Não achei muito legal...  :(

        public override string ToString()
        {
            //return base.ToString();
            return descricao.ToString();
        }
    }
}

Where am I going wrong?

    
asked by anonymous 13.05.2014 / 13:43

1 answer

7

Your problem is because DataGridView, when TextBox is popular, invokes the .ToString () method of the objects that populate it. So the solution you found is to override .ToString () in order to return what you want to display.

The ideal solution would be for DataGridView to display data from two different datasources, which however is not possible.

So, one way to solve your problem would be, at the time of popular DataGridView create a new anonymous type using LINQ and populate the DataGridView with the anonymous type.

var newList = lstUsr.Select(usuario => new
{
    Id = usuario.id,
    Nome = usuario.login,
    LoginNome = usuario.login,
    PerfilDescricao = usuario.perfil.descricao
}).ToList();

Changing your method:

    private void btnPreencheGrid_Click(object sender, EventArgs e)
    {
        var novaListUsuario = lstUsr.Select(usuario => new
            {
                Id = usuario.id,
                Nome = usuario.login,
                LoginNome = usuario.login,
                PerfilDescricao = usuario.perfil.descricao
            }).ToList();


        dgv.DataSource = null; //Limpa o grid;
        dgv.DataSource = novaListUsuario;
        dgv.Refresh();
    }

For this change to work, you need to edit the DataGridView and change the DataSource to (none) in the editor, as well as edit each of the columns that it understands.

That is, in each of the columns, change the DataPropertyName to match the name of the property in the anonymous type created with that popular column.

( Similar question in SO )

    
13.05.2014 / 16:30