Show property value instead of class name in DataGridView [closed]

2

I have a DataGridView that should show data between related tables and I can not show the data correctly, it shows the name of the nameSpace followed by the name of the class. I saw some things and they showed an override, but I also read that it is not good practice and suggested that you do it through the cellFormating event.

What happens to me is this:

ThisclassisintheDTOnamespace

publicclassDespesa{publicintid_despesa{get;set;}publicCategoriacategoria{get;set;}publicstringdescricao{get;set;}publicdecimalvalor{get;set;}publicMesmes{get;set;}publicstringprevisao{get;set;}publicForma_Pagamentoforma_Pagamento{get;set;}publicPeriodoperiodo{get;set;}}

Thenmyexpensecollectionwillinheritanexpenselist

publicclassDespesaCollection:List<Despesa>{}

InthebusinesslayerIputalltheexpenseswithinthecollection

foreach(DataRowlinhainDataTableDespesas.Rows){Despesadespesa=newDespesa();despesa.id_despesa=Convert.ToInt32(linha["id_despesa"]);
                despesa.categoria = new Categoria();
                despesa.categoria.id_categoria = Convert.ToInt32(linha["id_categoria"]);
                despesa.descricao = linha["descricao"].ToString();
                despesa.valor = Convert.ToDecimal(linha["valor"]);
                despesa.mes = new Mes();
                despesa.mes.id_mes = Convert.ToInt32(linha["id_mes"]);
                despesa.previsao = linha["previsao"].ToString();
                despesa.forma_Pagamento = new Forma_Pagamento();
                despesa.forma_Pagamento.id_forma_pagamento = Convert.ToInt32(linha["id_formaPagamento"]);
                despesa.periodo = new Periodo();
                despesa.periodo.id_periodo = Convert.ToInt32(linha["id_periodo"]);

                despesaCollection.Add(despesa);
            }

And here's how I load the collection to display in the dataGridView.

 private void carregarDataGridView()
    {
        DespesaCollection despesaCollection = new DespesaCollection();
        DespesaNegocio despesaNegocio = new DespesaNegocio();

        despesaCollection = despesaNegocio.ConsultarTudo();


        dataGridView1.DataSource = null;
        dataGridView1.DataSource = despesaCollection;
        dataGridView1.Refresh();
    }
    
asked by anonymous 07.10.2016 / 14:51

3 answers

5

First of all: Forget the history of using CellFormatting for this kind of thing. With a considerable amount of data, you will already begin to have performance problems, not to mention that there are much simpler ways of doing this.

From what you posted, I see no need to create a Collection to play the data on the grid. Since you're already following this pattern, maybe the best solution is actually overwriting the ToString() method of all your models , as long as it does not bother you at all.

As I understand it, you query the database, this query returns you a DataTable and from it you create a collection of Despesas to play on the grid. Having a DataTable , you can already bind to a DataGridView . So if all the necessary you need to show in the grid are in DataTable , you can do so

private void carregarDataGridView()
{
    var dataTable = RetonarDataTable(); // Vamos supor que este método devolva o datatable

    dataGridView1.DataSource = null;
    dataGridView1.DataSource = dataTable;
    dataGridView1.Refresh();
}

Another interesting way to solve this is to create an "intermediate class" that will only contain the information needed in grid . There, instead of instantiating a DespesaCollection , you can create a list of this class and do bind . See the example below

// essa é a classe "intermediária"
public class DespesaViewModel
{
    public int id_despesa { get; set; }
    public string nome_categoria { get; set; } // Apenas supus que deveria ser assim
    public string descricao { get; set; }
    public decimal valor { get; set; }
    public string descr_mes { get; set; } // Apenas supus que deveria ser assim
    public string previsao { get; set; }
    public string forma_pagamento_descr { get; set; } // Apenas supus que deveria ser assim
    public Periodo periodo { get; set; }
}


var listaDespesas = new List<DespesaViewModel>();
foreach (DataRow linha in DataTableDespesas.Rows)
{
    var despesaVm = new DespesaViewModel
    {
        id_despesa = Convert.ToInt32(linha["id_despesa"]);      
        nome_categoria = Convert.ToInt32(linha["nome_categoria"]);
        ///... assim por diante
    }

    listaDespesas.Add(despesaVm);
}

private void carregarDataGridView()
{
    var lista = CarregarLista();

    dataGridView1.DataSource = null;
    dataGridView1.DataSource = lista;
    dataGridView1.Refresh();
}
    
10.10.2016 / 02:04
5

Initially I see 2 options:

Include a new IdCategoria property in your DTO:

public class Despesa
{
    public int id_despesa { get; set; }
    public Categoria categoria { get; set; }
    public string descricao { get; set; }
    public decimal valor { get; set; }
    public Mes mes { get; set; }
    public string previsao { get; set; }
    public Forma_Pagamento forma_Pagamento { get; set; }
    public Periodo periodo { get; set; }

    public string IdCategoria 
    {
       get { return categoria.id_categoria; }
    }
}

Or make override of method ToString on object category:

public class Categoria
{
  .
  .
  .

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

(I'm not sure that the second option works correctly in your case)

(If @jbueno responds, you can mark his response.) He came to help you first :))

    
07.10.2016 / 19:54
2

When you bind an object of a non-primary type, winform calls the ToString method of that object. So if you override the ToString method of each of the classes you are showing (Category, Month, Form_Payment and Period) you can configure what appears on the grid.

For example, if I want to appear category_id

public class Categoria
{
  public override string ToString()
  {
    return id_categoria.ToString();
  }
}
    
10.10.2016 / 04:21