Conhecendo o ListView

O ListView, presente a várias versões do Delphi, tem a finalidade de mostrar itens em colunas, lista etc para dar a opção do usuário ter um controle de tela mais elegante. Nas últimas versões do Delphi, o componente, tem recebido features muito interessantes para que possamos usar cada vez mais em nossas aplicações. Neste artigo, vamos conhecer suas principais características.

Iniciando no básico

O ListView, permite que adicionemos itens manualmente, ou seja, podemos criar itens no controle, tanto em tempo de design, como em tempo de execução. Para criar itens, usamos a propriedade Items, onde temos um editor (Figura 1).

 


Figura 1. Editor do ListView do Delphi 2010

 

Além de itens, podemos adicionar subitens, que não são mostrados hierarquicamente, como poderia ser lógico, mas sim, ao lado do item. Os subitens apenas são mostrados quando usamos a propriedade  ViewStyle como vsReport e quando tivermos colunas (criadas através da propriedades Columns).

Feche o editor e veja como os mesmos são posicionados no ListView (Figura 2).

 

Figura 2. Itens posicionados no ListView

Veja que no editor, temos o Caption do item, assim como o índice de imagens. O item Group será visto adiante neste artigo. Para mostrar os items com imagens, devemos vincular um componente ImageList com as propriedades: GroupHeaderImage, LargeImages, SmallImages e StateImages.

Caso você não visualize nenhum item, temos uma propriedade que modifica o layout dos itens no ListView. Assim, temos as seguintes oções na propriedade ViewStyle:

  • Icon: mostra os itens em texto;

  • List: mostra os itens em uma lista;

  • SmallIcon; mostra os itens em ícones pequenos;

  • Report: mostra os itens em colunas (devemos criar as colunas na propriedade Columns).

Veja que temos que "brincar" com a propriedade para modificar o layout do ListView, de acordo com nossa preferência.

Configurações

Temos algumas propriedades interessantes que merecem uma passagem rápida.

  • CheckBoxes: adiciona um CheckBox no item;

  • GridLines: quando estiver utilizando colunas, coloca linhas, como se fosse um grid;

  • Group: defini os grupos do ListView;

  • GroupView: exibe os grupos definidos na propriedade Groups;

  • HotTrack: juntamente com HotTrackStyles, simula links para os itens do ListView;

  • MultiSelect: permite selecionar mais de um item;

  • RowSelect: quando estamos com vsReport em ViewStyle, a linha toda fica selecionada;

  • SorteType: indica a ordenação do items.

O conjunto dessas propriedades dará um visual diferente do componente. Um exemplo legal de utilizar em um ListView, quando você o utiliza como um Grid, é o efeito zebrado. Para fazer isso, adicione os itens e colunas manualmente no ListView.

No evento OnCustomDrawItem, use o código da Listagem 1.

Listagem 1. Efeito zebrado no ListView

with ListView1.Canvas.Brush do
begin
   if (Item.Index mod 2) = 0 then
      Color := clWhite
   else
      Color := clSilver;
end;

Veja na Figura 3, o ListView em execução.

 


Figura 3. Efeito zebrado no ListView

Mais customizações

Podemos ainda, customizar mais algumas características do controle. Exemplo: gostaria de mudar a cor da fonte da linha do ListView, de acordo com um valor mostrado no controle. As configurações de propriedades e eventos, são as mesmas do exemplo anterior. No evento, digite o código da Listagem 2.

 

Listagem 2. Modificando cor da linha do ListView

var
  qtde: integer;
begin
  qtde := StrToInt(Item.SubItems[1]);
  if qtde <= 9 then
  begin
    ListView1.Canvas.Font.Color := clRed;
    ListView1.Canvas.Font.Style :=
      ListView1.Canvas.Font.Style + [fsBold];
  end;
end;

 

Para entender, verificamos a terceira coluna, pois a primeira esta dentro da propriedade Itens e em SubItems iniciamos do indice zero. Assim, se o valor mostrado for menor que 9, a linha será mostrada em vermelho e negrito. Veja na Figura 4 o exemplo em execução.

 


Figura 4. Pintando o item do ListView de acordo com o valor

Para inserir ou remover itens em tempo de execução, devemos usar o código da Listagem 3.

Listagem 3. Adicionando e removendo itens do ListView

ADICIONAR

var
  item: TListItem;
begin
  item := ListView1.Items.Add;
  item.Caption := 'The';
  item.SubItems.Add('Club');
end;

 

REMOVER

ListView1.Items.Delete(ListView1.ItemIndex);

 

ou

ListView1.DeleteSelected;

 

Note, que para adicionar, temos que incluir o item e o subitem (quantos forem necessários). O item podemos considerar como sendo a coluna de índice zero (quando estamos usando vsReport no ViewStyle) e o subitem as colunas subsequentes (podem ser mais, lembre-se disso).

Para remover, precisamos pegar o índice do item para repassar para o Delete, ou podemos usar o DeleteSelected, que remove o item selecionado. Para o Delete, se não estiver item selecionado, um erro será mostrado, para contornar, basta verificar o valor de ItemIndex, que no caso, deve ser maior que -1.

Fonte de dados

Como você pode notar, o ListView não possui uma propriedade DataSource, nem um componente extendido com essa propriedade na aba DataControls. Assim, como podemos exibir dados de uma consulta no ListView? Simples, muito simples.

Vamos percorrer uma consulta e adicionar os itens via código. Crie uma conexão com seu banco de dados preferido, aqui, usaremos o SQL Server e o banco Northwind. Adicionaremos os dados da tabela Categories.

Use o código da Listagem 4 para incluir os itens da consulta.

 

Listagem 4. Adicionando itens via código baseado na consulta do banco

var
  i: integer;
  item: TListItem;
begin
  for i := 0 to ClientDataSet1.RecordCount - 1 do
  begin
    item := ListView1.Items.Add;
    item.Caption := ClientDataSet1CategoryName.AsString;
    item.SubItems.Add(ClientDataSet1Description.AsString);

    ClientDataSet1.Next;
  end;
end;

 

Veja que percorremos os itens do ClientDataSet da consulta e adicionamos os mesmos no ListView. Para isso, criamos uma variável do tipo TListItem, que recebe do método Add o mesmo tipo. Assim, basta configurar o texto e os subitens do controle. Fácil né? Veja na Figura 5 o exemplo em execução.

 


Figura 5. Preenchendo o ListView com consulta no banco

Grupos

A partir da versão 2009 do Delphi, o ListView apresenta uma feature bastante interessante, que é o agrupamento de itens. Assim, podemos criar um layout com grupos e itens, deixando o ListView e sua aplicação com uma apresentação mais profissional.

Para criar grupos, precisamos apenas criar os mesmos na propriedade Groups. No editor, podemos criar grupos e configurar suas propriedades. A seguir, as principais propriedades do grupo:

  • Footer: texto que será apresentado no rodapé do grupo;

  • FooterAlign: alinhamento do texto configurado na propriedade Footer;

  • Header: texto que será apresentado no cabeçalho do grupo;

  • HeaderAlign: alinhamento do texto configurado na propriedade Header;

  • SubsetTitle: texto que será mostrado abaixo do cabeçalho;

  • TitleImage: índice da imagem do grupo. Essa imagem deverá estar em um ImageList que será configurado na propriedade GroupHeaderImages.

Após a configuração o grupo, no editor onde criamos os itens (veja Figura 1), existe uma caixa de seleção onde vamos vincular o item ao grupo criado. Assim, temos o grupo e seus respectivos itens. Crie os grupos, itens e faça a vinculação.
Para finalizar, devemos passar para true a propriedade GroupView e ViewStyle para vsSmallIcon. Veja na Figura 6 um exemplo.

 


Figura 6. ListView com grupos

Criando grupos via código

Caso seja necessário, podemos criar os itens e grupos via código, semelhante ao exemplo anterior. O código da Listagem 5 mostra o código de criação dos grupos e itens.

Listagem 5. Criando grupos e itens

var
  grupo: TListGroup;
  item: TListItem;
  i, j, cont: integer;
begin
  ListView1.GroupView := true;
  //cria o grupo
  for i := 1 to 5 do
  begin
    grupo := ListView1.Groups.Add;
    grupo.Header := 'Grupo ' + IntToStr(i);
    grupo.GroupID := i;
    cont := 0;
    //para cada grupo, cria os itens
    for j := 1 to 4 do
    begin
      cont := cont + 1;
      item := ListView1.Items.Add;
      item.Caption := 'Item ' + IntToStr(j) + ' do Grupo ' + IntToStr(i);
      item.GroupID := i;
    end;
    //total do grupo
    grupo.Footer := 'Total de itens: ' + IntToStr(cont);
  end;
end;

 

Criamos uma variável do tipo TListGroup, que recebe do método Add o mesmo tipo. Assim, para cada grupo, criamos os itens, vinculando os mesmos usando a propriedade GroupID. Colocamos um contador que será mostrado no rodapé de cada grupo.

Claro, que nesse exemplo, usamos um laço fixo, então o contador será o mesmo valor. No próximo exemplo, usaremos uma consulta do banco, facilitando a visualização do exemplo. Veja na Figura 7 o exemplo em execução.

 

Figura 7. ListView com grupos e itens criados via código

Criando grupos com consulta do banco

Vamos agora, fazer um exemplo de criação de grupos, usando uma consulta do banco de dados. Vamos usar o banco Northwind com as tabelas Categories e Products, onde cada produto possui uma categoria, assim, cada grupo será uma categoria e os itens serão os produtos.

Nesse exemplo, usarei duas pesquisas, retornado todas as categorias e todos os produtos. A filtragem dos produtos de cada categoria será feita localmente, de acordo com o grupo.  Não vou mostrar como cria conexão com o banco, pois acredito ser algo simples e você pode usar qualquer tecnologia de acesso a dados para isso.
Veja na Listagem 6 o código para criação dos grupos e itens.

Listagem 6. Código para criação de grupos e itens, baseado em consulta

var
  grupo: TListGroup;
  item: TListItem;
  i, j: integer;
begin
  ListView1.GroupView := true;
  //cria o grupo
  for i := 0 to cdsCategorias.RecordCount - 1 do
  begin
    grupo := ListView1.Groups.Add;
    grupo.Header := cdsCategoriasCategoryName.AsString;
    grupo.GroupID := cdsCategoriasCategoryID.AsInteger;

    //filtra os produtos da categoria
    cdsProdutos.Filter := 'CategoryID = ' +
      cdsCategoriasCategoryID.AsString;
    cdsProdutos.Filtered := true;

    //para cada grupo, cria os itens
    for j := 0 to cdsProdutos.RecordCount - 1 do
    begin
      item := ListView1.Items.Add;
      item.Caption := cdsProdutosProductName.AsString;
      item.SubItems.Add(cdsProdutosUnitsInStock.AsString);
      item.SubItems.Add(FormatCurr('R$ #,#.00',
        cdsProdutosUnitPrice.AsCurrency));
      item.GroupID := cdsProdutosCategoryID.AsInteger;

      cdsProdutos.Next;
    end;
    //contador do grupo
    grupo.Footer := 'Total de produtos: ' +
      IntToStr(cdsProdutos.RecordCount);

    cdsProdutos.Filtered := false;

    cdsCategorias.Next;
  end;
end;

 

O código é simples, semelhante ao anterior. Usamos também o código da categoria (CategoryID) para fazer a vinculação dos itens com o grupo. Vamos criar três colunas no ListView e mudar ViewStyle para vsReport.
Podemos ainda vincular imagens dos grupos, conforme fizemos anteriormente, nesse exemplo, coloquei como índice o código da categoria. Veja o exemplo em execução na Figura 8.


Figura 8. ListView com grupos adicionados de uma consulta

 

Coloquei também como subtítulo o campo Description da categoria.

Conclusão

Vimos nesse artigo, que o ListView pode ser um componente bastante útil para usarmos em nossas aplicações, seja com dados estáticos como com dados dinâmicos, oriundos de consultas ao banco de dados.
Um grande abraço a todos e sucesso em seus projetos!

 

Sobre o Autor

Luciano Pimenta (lucianoalmeidapimenta@gmail.com) é Técnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicações Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4ª edição da Borland Conference (BorCon). Autor de mais de 50 artigos e de mais de 250 vídeo aulas publicadas em revistas e sites especializados. Atualmente é programador Web da FullSoft - Mobile Solutions em Caxias do Sul-RS. Blog: lucianopimenta.blogspot.com.

E-mail: www.lucianopimenta.com

The Club - O Maior Clube de programadores do Brasil