Fill Data Grid View with object property

Asked

Viewed 17,765 times

9

I have a form where I need to fill out a DataGridView with data from a user list. 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();
        }
    }
} 

Class User List

using System.Collections.Generic;

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

Class Profile

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

Form Archive:

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, on the property DataPropertyName, i configure as follows the name of the columns and what should be presented in them:

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, fine, but the profile column, is not filled leaving my datagridview like this:

I found a solution, where they talked to override the method toString of the Profile class and configure the DataPropertyName column 4 as "profile", but I didn’t find it very cool, see:

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?

1 answer

8


Its problem is due to the fact that Datagridview, when the Textbox is popular, invokes the . Tostring() method of the objects that make it popular. Hence the solution found consists of overriding . tostring() in order to return what belongs to show.

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

Thus, one way to solve your problem would be, at the time of popular Datagridview create a new anonymous type using LINQ and fill 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();

By 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 it is necessary to edit the Datagridview and change the Datasource to (None) in the editor, as well as edit each of the columns that belong.

That is, in each of the columns, change the Datapropertyname to match the name of the property in the created anonymous type with which the column belongs.

(Similar question in the OS)

  • 2

    Perfect Omni, worked exactly as I needed.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.