none
Objeto(List<>) com DataGridView RRS feed

  • Pergunta

  • Olá Galera, estou com um problema com um DataGridView e um List<Objeto>, estou tentando acessar uma propriedade do meu Objeto (Empresa) e dentro desse objeto eu tenho um outro Objeto (Municipio) esse Municipio contém as propriedades de ID, Nome e UF, preciso que na propriedade da Coluna da GridView ele set o nome da minha cidade, vi que existe a propriedade DataPropertyName que você relaciona as propriedades da sua lista com as colunas da Grid, mas não consegui acessar esse Objeto Municipio.Nome. Alguém poderia me ajudar?
    quinta-feira, 7 de fevereiro de 2013 18:28

Respostas

  • Boa tarde Gui!

    O DataGridView realmente não "enxerga" uma propriedade dentro da outra, uma maneira de resolver esta questão é utilizando tipos anônimos, segue um exemplo com o code comentado:

      //Classe UF
            public class Uf
            {
                public string NomeEstado { get; set; }
            }
    
            //Classe Cidade
            public class Cidade
            {
                public int Id { get; set; }
                public string Nome { get; set; }
                public Uf UF { get; set; }
            }
    
            //Evento Load do Formulário
            private void Form1_Load(object sender, EventArgs e)
            {
                //instância e criação do list
                var listaNormal = new List<Cidade>()
                                {
                                    //Aqui os valores contidos no mesmo
                                    new Cidade(){Id=1,Nome="Marataízes",UF=new Uf(){NomeEstado="ES"}},
                                    new Cidade(){Id=2,Nome="Rio de Janeiro",UF=new Uf(){NomeEstado="RJ"}},
                                    new Cidade(){Id=3,Nome="São Paulo",UF=new Uf(){NomeEstado="SP"}}
                                };
    
                //Instância da nova lista que irá conter os "novos tipos"
                var listaNovoTipo = (from item in listaNormal
                                     select new
                                                {
                                                    //Aqui nomeio as propriedades que irão conter os valores
                                                    //como desejado e são estes novos nomes que serão colocados
                                                    //na propriedade DataPropertyName do DGV ou seja serão
                                                    //"Id","Nome", "NomeEstado" que será o nosso novo tipo
                                                    Id = item.Id,
                                                    Nome = item.Nome,
                                                    NomeEstado = item.UF.NomeEstado
    
                                                }).OrderBy(x => x.Nome).ToList();
    
                //Aqui vinculo a nova lista com os tipos criados
                //ao datasource do dgv
                dataGridView1.DataSource = listaNovoTipo;
            }

    Resultado Obtido:


     "Feliz aquele que transfere o saber e aprende o que ensina."(Cora Coralina)


    Pablo Batista Cardoso
    www.pablobatistacardoso.com.br
    pablobatistacardoso@hotmail.com

    • Sugerido como Resposta Levi DomingosModerator domingo, 10 de fevereiro de 2013 17:56
    • Marcado como Resposta Gui.Maia quinta-feira, 14 de fevereiro de 2013 12:40
    sábado, 9 de fevereiro de 2013 17:33

Todas as Respostas

  • Isso é um problema... no asp.net ele até aceita fazer isso sem problemas...

    Uma solução que fiz foi criar uma coluna customizada que aceite valores do tipo

    "Municipio.Nome".

    Quando chegar do trabalho eu posto como fiz, mas de outra forma, acredito que só alterando o valor da coluna nos eventos da grid.

    quinta-feira, 7 de fevereiro de 2013 18:55
  • Você não pode usar as propriedades EVAL("Municipio.Nome") dentro do datagrid??

    <asp:TemplateColumn>
    <HeaderTemplate>
                            Municipio Nome
    </HeaderTemplate>
    <ItemTemplate>
    <%# Eval("Municipio.Nome") %>
    </ItemTemplate>
    </asp:TemplateColumn>

    Abraço


    Se for útil marcar como resposta Para que outros Aproveitem


    • Editado Jones Roberto quinta-feira, 7 de fevereiro de 2013 21:25
    quinta-feira, 7 de fevereiro de 2013 21:23
  • Olá Eric e Jones, me desculpe eu não estou usando aps.net estou usando C# windows form e o componente é o DataGridView.
    sexta-feira, 8 de fevereiro de 2013 13:48
  • Boa tarde Gui!

    O DataGridView realmente não "enxerga" uma propriedade dentro da outra, uma maneira de resolver esta questão é utilizando tipos anônimos, segue um exemplo com o code comentado:

      //Classe UF
            public class Uf
            {
                public string NomeEstado { get; set; }
            }
    
            //Classe Cidade
            public class Cidade
            {
                public int Id { get; set; }
                public string Nome { get; set; }
                public Uf UF { get; set; }
            }
    
            //Evento Load do Formulário
            private void Form1_Load(object sender, EventArgs e)
            {
                //instância e criação do list
                var listaNormal = new List<Cidade>()
                                {
                                    //Aqui os valores contidos no mesmo
                                    new Cidade(){Id=1,Nome="Marataízes",UF=new Uf(){NomeEstado="ES"}},
                                    new Cidade(){Id=2,Nome="Rio de Janeiro",UF=new Uf(){NomeEstado="RJ"}},
                                    new Cidade(){Id=3,Nome="São Paulo",UF=new Uf(){NomeEstado="SP"}}
                                };
    
                //Instância da nova lista que irá conter os "novos tipos"
                var listaNovoTipo = (from item in listaNormal
                                     select new
                                                {
                                                    //Aqui nomeio as propriedades que irão conter os valores
                                                    //como desejado e são estes novos nomes que serão colocados
                                                    //na propriedade DataPropertyName do DGV ou seja serão
                                                    //"Id","Nome", "NomeEstado" que será o nosso novo tipo
                                                    Id = item.Id,
                                                    Nome = item.Nome,
                                                    NomeEstado = item.UF.NomeEstado
    
                                                }).OrderBy(x => x.Nome).ToList();
    
                //Aqui vinculo a nova lista com os tipos criados
                //ao datasource do dgv
                dataGridView1.DataSource = listaNovoTipo;
            }

    Resultado Obtido:


     "Feliz aquele que transfere o saber e aprende o que ensina."(Cora Coralina)


    Pablo Batista Cardoso
    www.pablobatistacardoso.com.br
    pablobatistacardoso@hotmail.com

    • Sugerido como Resposta Levi DomingosModerator domingo, 10 de fevereiro de 2013 17:56
    • Marcado como Resposta Gui.Maia quinta-feira, 14 de fevereiro de 2013 12:40
    sábado, 9 de fevereiro de 2013 17:33
  • Então... por isso eu falei, no asp.net permitem isso... ja no windows forms não...

    Vou postar o código da coluna que fiz pra me ajudar nisso... 

    Atenção. O Código é "AS IS", eu fiz isso realmente pra me ajudar num projeto caseiro pra evitar de ficar fazendo "workarounds"... notei que se eu inserir muiiiiiiitos dados ele ficará lento por conta do uso de reflection, mas pra poucos dados funciona normal até onde testei.

     1- Crie uma classe com o nome: EFOTDataGridTextColumn.cs 

    2 - apague tudo que estiver na classe criada e cole o código abaixo.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace EFOT.FIN.UI.Controles
    {
        
        /// <summary>
        /// Coluna
        /// </summary>
        /// <remarks>Criado por Eric Felipe de O. Torres - ericfelipe99@hotmail.com</remarks>
        public class EFOTDataGridTextColumn: System.Windows.Forms.DataGridViewColumn
        {
            public EFOTDataGridTextColumn(): base(new EFOTDataGridTextColumnCell())
            {}
            
        }
    
    
        /// <summary>
        /// Lógica de como a celula exibirá e setará os valores exibidos no gridview.
        /// </summary>
        /// <remarks>Criado por Eric Felipe de O. Torres - ericfelipe99@hotmail.com</remarks>
        public class EFOTDataGridTextColumnCell : System.Windows.Forms.DataGridViewTextBoxCell
        {
            protected override object GetValue(int rowIndex)
            {
                this.ConfigurarComplexTypeBinding(rowIndex);
    
                if (_ComplexTypePropertyInfo == null)
                    return base.GetValue(rowIndex);
    
                return _ComplexTypePropertyInfo.GetValue(this._ComplexTypeObject, null);
    
            }
    
            public override Type ValueType
            {
                get
                {
                    if (_ComplexTypePropertyInfo != null)
                        return _ComplexTypePropertyInfo.PropertyType;
    
                    return base.ValueType;
                }
            }
    
            protected override bool SetValue(int rowIndex, object value)
            {
                this.ConfigurarComplexTypeBinding(rowIndex);
    
                if (_ComplexTypeObjectType == null)
                    return base.SetValue(rowIndex, value); 
    
                try
                {
                        
                    this._ComplexTypePropertyInfo.SetValue(this._ComplexTypeObject, value, null);
                    return true;
                }
                catch{}
    
                return false;
    
            }
    
            private System.Type _ComplexTypeObjectType = null;
            System.Reflection.PropertyInfo _ComplexTypePropertyInfo = null;
            private object _ComplexTypeObject = null;
            private string _ComplexTypeObjectPropertyValue = null;
    
            private void ConfigurarComplexTypeBinding(int rowIndex)
            {
                if (this.DataGridView == null || this.DataGridView.Rows[rowIndex].DataBoundItem == null || string.IsNullOrWhiteSpace(this.OwningColumn.DataPropertyName))
                    return;
    
                this._ComplexTypeObject = this.DataGridView.Rows[rowIndex].DataBoundItem;
                this._ComplexTypeObjectType = this._ComplexTypeObject.GetType();
                this._ComplexTypeObjectPropertyValue = this.OwningColumn.DataPropertyName;
    
                if (this.OwningColumn.DataPropertyName.Contains("."))
                {
                    string[] typename = this.OwningColumn.DataPropertyName.Split('.');
                    System.Reflection.PropertyInfo pinfo = null;
    
                    for (var i = 0; i < typename.Length; i++)
                    {
                        _ComplexTypeObjectPropertyValue = typename[i];
    
                        pinfo = _ComplexTypeObjectType.GetProperty(_ComplexTypeObjectPropertyValue);
                        _ComplexTypePropertyInfo = pinfo;
    
                        if (!pinfo.PropertyType.IsClass)
                        {
                            return;
                        }
                        else
                        {
                            _ComplexTypeObject = pinfo.GetValue(_ComplexTypeObject, null);
                            _ComplexTypeObjectType = _ComplexTypeObject.GetType();
                        }
    
                    }
                }
            }
    
    
        }
    }

    Agora no designer do visual studio, terá um novo tipo de coluna. 

    3 - Adicione uma coluna no seu gridview do tipo EFOTDataGridTextColumn (adicione uma coluna e na propriedade ColumnType altere para EFOTDataGridTextColumn)

    4 - Na propriedade DataPropertyName pode adicionar valores da seguinte maneira:

    Produto.IdProduto

    Produto.Categoria.Nome


    domingo, 10 de fevereiro de 2013 15:24
  • Obrigado a todos pela ajuda nesse problema, e a dica do Pablo funcionou corretamente como eu precisava.
    quinta-feira, 14 de fevereiro de 2013 12:41