none
Duvida Reflection RRS feed

  • Pergunta

  • Pessoal,

    Estou testando um parametro passado como um object dessa forma:

    (Contribuição do Gustavo)

    private void teste(objet obj)
    {
    if (typeof(System.Linq.IQueryable).IsInstanceOfType(obj))
    ...
    }

    Até ai blz, eu consigo testar se o objeto é um IQueryable.
    A intenção é preencher um listview com ele, mas não estou conseguindo pegar os nomes dos campos, tamanho e valor.
    Com reflection é possível não é ?

    Agradeço qualquer ajuda
    Sanses

    sexta-feira, 16 de abril de 2010 11:57

Respostas

  • Sanses,

    Sua lógica para preencher a TreeView está errada. O correto seria:

    private void PreencherListViewIQueryable<T>(IQueryable<T> queryable, ListView listView)
    {
        // tipo
        Type t = typeof(T);

        // propriedades do tipo
        var properties = t.GetProperties();

        // verifica quantidade de propriedades
        if (properties.Length == 0)
            return;

        // inicia edição do ListView
        listView.BeginUpdate();

        // limpa itens (colunas e linhas)
        listView.Clear();

        // cria colunas
        foreach (var p in properties)
            listView.Columns.Add(p.Name);

        // cria itens
        foreach (var item in queryable)
        {
            // cria item
            var listViewItem = new ListViewItem(properties[0].GetValue(item, new object[] {}).ToString());

            // adiciona sub-itens
            for (int i = 1; i < properties.Length; ++i)
                listViewItem.SubItems.Add(properties[i].GetValue(item, new object[] { }).ToString());

            // adiciona item na ListView
            listView.Items.Add(listViewItem);
        }

        // finaliza edição do ListView
        listView.EndUpdate();
    }

    Você realmente precisa utilizar o componente ListView? É possível utilizar também um DataGridView .

    Att.

    Ari C. Raimundo
    MCAD, MCTS
    http://araimundo.blogspot.com

    • Marcado como Resposta Silmar Sanches segunda-feira, 19 de abril de 2010 02:47
    domingo, 18 de abril de 2010 04:09
    Moderador

Todas as Respostas

  • Pessoal,

    Estou testando um parametro passado como um object dessa forma:

    (Contribuição do Gustavo)

    private void teste(objet obj)
    {
    if (typeof(System.Linq.IQueryable).IsInstanceOfType(obj))
    ...
    }

    Até ai blz, eu consigo testar se o objeto é um IQueryable.
    A intenção é preencher um listview com ele, mas não estou conseguindo pegar os nomes dos campos, tamanho e valor.
    Com reflection é possível não é ?

    Agradeço qualquer ajuda
    Sanses

    http://weblogs.asp.net/ysolodkyy/archive/2007/10/07/using-linq-with-system-reflection-classes.aspx

     

    http://weblogs.asp.net/cazzu/archive/2006/07/06/Linq-beyond-queries_3A00_-strong_2D00_typed-reflection_2100_.aspx


    Just Be Humble Malange!
    sexta-feira, 16 de abril de 2010 12:03
    Moderador
  • Malange,

    Vou testar aqui e ver o que consigo, mais acredito que não funcione pelo mesmo motivo que obtive nos testes anteriores: em todos os exemplo deste linqhttp://weblogs.asp.net/ysolodkyy/archive/2007/10/07/using-linq-with-system-reflection-classes.aspx ele passa o tipo da classe, e é justamente isso que está dificultando. Eu não passo nenhuma referencia a qualquer classe com definições de campos e etc. O que eu quero é receber o objeto e em tempo de execução, busccar o tipo dele e varrer quais propriedades ele tem. Ai tendo estas propriedades em um array, eu coloco como coluna do listview. O mesmo depois para os dados.

    Sanses

    sexta-feira, 16 de abril de 2010 12:14
  • Malange,

    Não funcionou. Eu preciso passar o resultado de uma consulta feita via linq e pegar o tipo da classe e os atributos. Seria um metodo que recebe um tipo IQueryable e preenche um listview.

    Neste exemplo que vc me passou eu tenho que instanciar uma classe, mais esse método seria para todas as classes da aplicação, por isso não posso instancia-la.

    Sanses

    sexta-feira, 16 de abril de 2010 16:42
  • Malange,

    Não funcionou. Eu preciso passar o resultado de uma consulta feita via linq e pegar o tipo da classe e os atributos. Seria um metodo que recebe um tipo IQueryable e preenche um listview.

    Neste exemplo que vc me passou eu tenho que instanciar uma classe, mais esse método seria para todas as classes da aplicação, por isso não posso instancia-la.

    Sanses

    http://bartdesmet.net/blogs/bart/archive/2007/04/06/the-iqueryable-tales-linq-to-ldap-part-2-getting-started-with-iqueryable-t.aspx
    Just Be Humble Malange!
    sexta-feira, 16 de abril de 2010 17:46
    Moderador
  • ????
    sexta-feira, 16 de abril de 2010 18:15
  • Sanses,

    Não sei se entendi muito bem a sua dúvida, mas talvez o método que criei abaixo pode lhe ajudar. O método solicita um IQueryable<T> e mostra, para cada item, os nomes das propriedades e seus valores.

    static void DumpIQueryable<T>(IQueryable<T> queryable)
    {
        // tipo
        Type t = typeof(T);

        // propriedades do tipo
        var properties = t.GetProperties();

        // loop
        foreach (var item in queryable)
        {
            // mostra propriedade e valor
            foreach (var property in properties)
                Console.WriteLine("{0}: {1}", property.Name, property.GetValue(item, null));
        }
    }

    Para utiliza o método você faria assim:

    using (SeuDataContext dc = new SeuDataContext())
    {
        var q = ... // consulta que retorna IQueryable<T>
        DumpIQueryable(q);
    }

    Obs: Utilizei o método em uma aplicação console por simplicidade.

    Att.

    Ari C. Raimundo
    MCAD, MCTS
    http://araimundo.blogspot.com

    sexta-feira, 16 de abril de 2010 19:24
    Moderador
  • Ari,

    É exatamente isso. Show de bola. Só faltou eu conseguir preencher o listview separanto os valores nas colunas.

    Fiz assim, mais dá mensagem de que a contagem de parametros não coicide:

    private void DumpIQueryable<T>(IQueryable<T> queryable)
        {
          // tipo
          Type t = typeof(T);
    
          // propriedades do tipo
          var properties = t.GetProperties();
    
          // loop
          foreach (var item in queryable)
          {
            // mostra propriedade e valor
            foreach (var property in properties)
            {
              listView1.Columns.Add(property.Name);
            }
            foreach (var prop in properties)
            {
              ListViewItem lv = new ListViewItem();
              lv.Text = prop.GetValue(item, new object[] { prop.Name}).ToString();
              listView1.Items.Add(lv);
            }
          }
        }

    sabe como posso separar os valores de cada propriedade ?

     

    Grato

    Sanses

    sábado, 17 de abril de 2010 06:10
  • Sanses,

    Na verdade uma parte do seu código está errada, você está passando o nome da propriedade como argumento. O correto seria:

    lv.Text = prop.GetValue(item, new object[] {}).ToString();

    Somente como dica, quando você adiciona items um por um no controle ListView, o correto é utilizar os métodos BeginUpdate e EndUpdate.

    ListView.BeginUpdate Method
    http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.beginupdate.aspx

    ListView.EndUpdate Method
    http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.endupdate.aspx

    Att.

    Ari C. Raimundo
    MCAD, MCTS
    http://araimundo.blogspot.com

    sábado, 17 de abril de 2010 19:26
    Moderador
  • Ari,

    Com o código abaixo eu consegui preencher as colunas corretamente, mas está dando um erro no index quando vou preencher os items:

    private void DumpIQueryable<T>(IQueryable<T> queryable)
        {
          // tipo
          Type t = typeof(T);
    
          // propriedades do tipo
          var properties = t.GetProperties();
    
          for (int i = 0; i < properties.Count(); i++)
          {
            listView1.Columns.Add(properties[i].Name);
          }
    
          foreach (var item in queryable)
          {
            for (int i = 0; i < properties.Count(); i++)
            {
              ListViewItem lv = new ListViewItem();
              lv.SubItems[i].Text = properties[i].GetValue(item, null).ToString();
              listView1.Items.Add(lv);
            }
          }
        }

    dessa forma ele cria as colunas, mais quando entra no laço que preenche o items, ele pega o primeiro valor coloca na list e dá erro.  Tipo, o valor 0 existe já o 1 não. . .e isso não consegui resolver.

    No laço o valor de item fica igual á "{ cod = 3, nome = EMPRESA ME, fone = (11)1111-1111 }", se não achar outra forma, vou ter que tratar esta string...

    Obrigado pela atenção

    Sanses

     

     

    sábado, 17 de abril de 2010 19:34
  • Sanses,

    Sua lógica para preencher a TreeView está errada. O correto seria:

    private void PreencherListViewIQueryable<T>(IQueryable<T> queryable, ListView listView)
    {
        // tipo
        Type t = typeof(T);

        // propriedades do tipo
        var properties = t.GetProperties();

        // verifica quantidade de propriedades
        if (properties.Length == 0)
            return;

        // inicia edição do ListView
        listView.BeginUpdate();

        // limpa itens (colunas e linhas)
        listView.Clear();

        // cria colunas
        foreach (var p in properties)
            listView.Columns.Add(p.Name);

        // cria itens
        foreach (var item in queryable)
        {
            // cria item
            var listViewItem = new ListViewItem(properties[0].GetValue(item, new object[] {}).ToString());

            // adiciona sub-itens
            for (int i = 1; i < properties.Length; ++i)
                listViewItem.SubItems.Add(properties[i].GetValue(item, new object[] { }).ToString());

            // adiciona item na ListView
            listView.Items.Add(listViewItem);
        }

        // finaliza edição do ListView
        listView.EndUpdate();
    }

    Você realmente precisa utilizar o componente ListView? É possível utilizar também um DataGridView .

    Att.

    Ari C. Raimundo
    MCAD, MCTS
    http://araimundo.blogspot.com

    • Marcado como Resposta Silmar Sanches segunda-feira, 19 de abril de 2010 02:47
    domingo, 18 de abril de 2010 04:09
    Moderador
  • Ari,

    Valew pela força. Show de bola. Só preciso agora pegar o tamanho das colunas, será que é possível ?

    Sanses

    segunda-feira, 19 de abril de 2010 02:48