Clique para saber mais...
  Home     Download     Produtos / Cursos     Revista     Vídeo Aulas     Fórum     Contato   Clique aqui para logar | 12 de Junho de 2026
  Login

Codinome
Senha
Salvar informações

 Esqueci minha senha
 Novo Cadastro

  Usuários
82 Usuários Online

  Revista ActiveDelphi
 Assine Já!
 Edições
 Sobre a Revista

  Conteúdo
 Apostilas
 Artigos
 Componentes
 Dicas
 News
 Programas / Exemplos
 Vídeo Aulas

  Serviços
 Active News
 Fórum
 Produtos / Cursos

  Outros
 Colunistas
 Contato
 Top 10

  Publicidade

  [Artigos]  Dicas sobre o componente DBGrid do Delphi
Publicado por rboaro : Sexta, Janeiro 18, 2013 - 07:56 GMT-3 (1169 leituras)
Comentários 12 Comentários   Enviar esta notícia a um amigo Enviar para um amigo   Versão para Impressão Versão para impressão
Diego Garcia O Dbgrid talvez seja um dos componentes mais utilizados no dia a dia de um desenvolvedor delphi, principalmente em soluções comerciais, isso graças ao fato de que o uso deste componente seja definitivamente a maneira mais simples e mais rápida de apresentar dados de um dataSet para o usuário, seja esse dataSet o resultado de uma pesquisa em um banco de dados, registros temporários, etc. Na grande realidade o conceito de grid está presente em qualquer ambiente de desenvolvimento.

Neste post eu resolvi juntar algumas dicas simples e práticas para melhorar a utilização deste componente. Para melhor demonstrar os resultados dos exemplos, criei um projeto teste com dados fictícios em um ClienteDataSet, porem, os exemplos que fiz são quase que 100% independentes do tipo de dataSet utilizado.

Fazer linha zebrada:
Vamos usar a lógica mais utilizada para zebrar linhas em um grid, verificar se o numero do registro atual do dataSet é impar ou par, veja que não estou falando do valor de algum campo do dataSet, mas sim o numero da linha dentro do dataSet. Para recuperar essa informação, nos dataSet temos a propriedadeRecNo que consiste no numero do registro ativo no dataSet e para saber se esse numero é impar ou par, basta usar o método Odd que retornar true se um numero é impar e false se esse for par. Para implementar essa rotina, iremos utilizar o eventoOnDrawColumnCell do DbGrid que consiste no evento em que os dados são “desenhados” no grid.

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
with DBGrid1 do
begin
if Odd( DataSource.DataSet.RecNo) then
Canvas.Brush.Color := clSilver
else
Canvas.Brush.Color := clMoneyGreen;

Canvas.FillRect(Rect);
DefaultDrawColumnCell(Rect,DataCol,Column,State);
end;
end;
Note que para customizar a visualização do meu grid, eu utilizei a propriedade Canvas, é nesta propriedade que ficam as configurações de tela do grid. Dentro da propriedade canvas, eu tenho a propriedade Brush, que é utilizada para pintar o fundo de uma linha no grid. O resultado deste exemplo ficaria desta forma.


Destacar linhas:
Muitas vezes precisamos dar algum destaque visual para determinados registros dependendo de alguma condição, para isso, podemos alterar dinamicamente a formatação de fonte ou até mesmo a cor de fundo de uma linha do DBGrid. Seguindo os dados que criei para os exemplos faremos com que, os registros que tiverem um valor maior do que 2500 no campo salario fiquem com a linha vermelha quando selecionados e os não selecionados fiquem com a fonte vermelha e em negrito.
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
with DBGrid1 do
begin
if DataSource.DataSet.FieldByName('salario').AsFloat > 2500 then
begin
if (gdSelected in State) then
Canvas.Brush.Color := clRed
else
begin
Canvas.Font.Style := [fsBold];
Canvas.Font.Color := clRed;
end
end;
Canvas.FillRect(Rect);
DefaultDrawColumnCell(Rect,DataCol,Column,State);
end;
end;
Comparando com o exemplo anterior não temos muitas diferenças, a não ser pela verificação gdSelected in State, caso esta verificação resulte em true significa que neste momento o DBGrid está desenhando a linha selecionada. Neste o exemplo, o resultado ficaria desta forma.



Destacar uma célula e uma coluna:
Este exemplo, não chega a ser muito diferente do anterior, por isso, mantive a mesma lógica, a coluna referente ao campo salario ficará com o fundo cinza, porem, caso algum registro tenha uma valor neste campo maior do que 2500, a célula ficará com o fundo vermelho e a fonte amarela.

procedure TfrmPrincipal.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
with DBGrid1 do
begin
if AnsiLowerCase(Column.FieldName) = 'salario' then
begin
Canvas.Brush.Color := clSilver;
if Column.Field.AsFloat > 2500 then
begin
Canvas.Brush.Color := clRed;
Canvas.Font.Color := clYellow;
end;
end;
Canvas.FillRect(Rect);
DefaultDrawColumnCell(Rect,DataCol,Column,State);
end;
end;
Talvez a diferença mais importante entre este exemplo e o anterior é a verificação feita pela coluna, ou seja, a manipulação do canvas é feita somente quando a coluna salario está sendo desenhada. Rodando esse exemplo em nossa base de estudo, teríamos o seguinte resultado.



Inserir um checkbox em um coluna:
Esse exemplo foi particularmente muito útil para mim no meu dia a dia, tanto que quando pensei em fazer esse post, foi o primeiro exemplo que separei para demonstrar. Ainda no evento OnDrawColumnCell, assim como no exemplo anterior, primeiramente precisamos saber se estamos desenhando a coluna que recebera o checkBox para, ai sim, inserir o componente no grid.
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
IS_CHECK : Array[Boolean] of Integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
var
Check : Integer;
R : TRect;
begin
with DBGrid1 do
begin
if AnsiLowerCase(Column.FieldName) = 'selecionado' then
begin
Canvas.FillRect(Rect);
Check := IS_CHECK[Column.Field.AsBoolean];
R := Rect;
InflateRect(R,-2,-2); //aqui manipula o tamanho do checkBox
DrawFrameControl(Canvas.Handle,rect,DFC_BUTTON,Check)
end;
end;
end;

O código acima alem de inserir o checkBox no campo selecionado já define se este checkBox vai estar marcado ou desmarcado, de acordo com o valor do campo em questão, através da variável Check, o resultado deste exemplo ficaria desta forma.



Para deixar um pouco mais prático o uso do checkBox no DBgrid, podemos fazer uma rotina para marcar ou desmarcar o componente quando a célula que ele está seja clicada
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
if Column.Field.FieldName = AnsiLowerCase('selecionado') then
begin
with DBGrid1.DataSource.DataSet do
begin
edit;
FieldByName('selecionado').Value := not FieldByName('selecionado').AsBoolean;
Post;
end;
end;
end;

Inserir uma imagem em uma coluna:
Eu particularmente usei pouco esse recurso mas todas as vezes que usei gostei bastante do resultado, a parte boa é que é bem simples de fazer. Como auxilio vamos utilizar um componente TImageList para poder armazenar as imagens que iremos utilizar. Trabalhando com a ideia do camposelecionado, vamos inserir duas imagens no TImageList e já deixar com que a imagem referente ao valor False do campo fique com o índice zero enquanto que a referente ao valor True fique com o índice 1.



Agora basta desenhar as imagens no DBGrid de acordo com a coluna e o valor da coluna.
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
with DBGrid1 do
begin
if AnsiLowerCase(Column.FieldName) = 'selecionado' then
begin
Canvas.FillRect(Rect);
ImageList1.Draw(Canvas,Rect.Left+10,Rect.Top+1,Ord(Column.Field.AsBoolean));
end;
end;
end;
Simples não? Até mais simples do que o checkBox, apesar de nem sempre deixar o visual mais profissional.



Utilizar um ComboBox em uma coluna:
A técnica de utilizar um ComboBox em um grid é feita de uma forma um pouco diferente dos exemplos anteriores, dentro das Columns do Dbgrid existe a propriedade PickList que consiste em um objeto do tipo TStrings e é utilizado exatamente para dar esse efeito do combo dentro de uma célula do grid. Então para demonstrar a utilização desta propriedade, dentro do meu método de carregar os dados, eu coloquei o seguinte trecho de código:
with Dbgrid1.Columns[2].PickList do //coluna referente ao cargo
begin
Clear;
Add('GERENTE');
Add('REPRESENTANTE');
Add('ENCANADOR');
Add('VENDEDOR');
end;
Obviamente este é apenas um exemplo didático, em uma situação real poderíamos carregar esta propriedade com valores vindos de uma tabela de validação por exemplo. O código acima daria o seguinte efeito:



Ordenar dinamicamente pela coluna clicada pelo usuário:
Por experiencia eu digo que a ordenação dos dados em um DBgrid é uma das coisas mais importantes na hora de apresentar dados para um usuário, mas é normal surgir a pergunta, como saber por qual campo ordenar os dados? Simples, permita que o usuário escolha por qual campo ele quer fazer a ordenação. Pode parecer que não, mas é algo simples, neste exemplo faremos com que quando o usuário clique no titulo de uma coluna no DBgrid, este seja ordenado pelo campo desta coluna. Para deixar mais intuitivo para o usuário, vamos mudar o icone do mouse quando este estivar passando pelo titulo dos campos no DBGrid, através do método OnMouseMove
procedure TForm1.DBGrid1MouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
var
mousePt: TGridcoord;
begin
mousePt := DbGrid1.MouseCoord(x,y);
if mousePt.y = 0 then
Screen.Cursor := crHandPoint
else
Screen.Cursor := crDefault;
end;

Esse método MouseCoord do DBgrid, retorna dentro um record de TGridcoord, em qual linha (Y) e em qual coluna (X) do grid o cursor do mouse está, por exemplo se você estiver com o cursor do mouse na segunda linha e terceira coluna, teríamos os seguintes valores no TGridcoord.Y e TGridcoord.X
Y = 2;
X = 3;
Agora vamos efetivamente fazer a ordenação dos dados. Para deixar um pouco mais visual, vamos também deixar em negrito o titulo da coluna em que o DBgrid está ordenado. A ordenação dos dados com clientDataSet fica fácil graças a propriedade IndexFieldNamesque define por quais campos o clientDataSet será indexado. Sendo assim no métodoOnTitleClick, basta colocar o seguinte código:
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
I: Integer;
begin
for I := 0 to DBGrid1.Columns.Count - 1 do
DBGrid1.Columns[i].Title.Font.Style := [];
TClientDataSet(DBGrid1.DataSource.DataSet).IndexFieldNames := Column.FieldName;
Column.Title.Font.Style := [fsBold];
end;

Seguindo este exemplo, ao clicar no titulo da coluna nome o resultado seria este.



Talvez este seja o único exemplo que faça com as dicas deste post não sejam 100% compatíveis com qualquer dataSet, pois utilizamos um método próprio de ClientDataSets, porem isso não significa que não seja possível fazer este exemplo com outros tipos de dataSets, basta fazer uma ou outra adaptação.



Comentários Comentários
   Ordem:  
Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos.


por: thiago.rj (thiago_globo05@hotmail.com) : Jan 18, 2013 - 11:35
(Informações sobre o membro | Enviar uma mensagem) http://http://
Gostei muito do artigo. Super didático e de suma importância. Parabéns!


por: alanito (alane.rf@gmail.com) : Jan 18, 2013 - 01:26
(Informações sobre o membro | Enviar uma mensagem) http://
Parabéns pelo artigo, o TDBGrid é um componente muito utilizado e contém vários recursos, essas dicas foram bastante interessantes.


por: johnsson (nobigrider@msn.com) : Jan 18, 2013 - 02:20
(Informações sobre o membro | Enviar uma mensagem) http://http://
Um excelente guia rápido.


por: thiago_e3 (thiago.e03@gmail.com) : Jan 20, 2013 - 12:02
(Informações sobre o membro | Enviar uma mensagem) http://http://
Parabéns... juntei suas dicas e acabei criando um padrão aos DbGrid's de um projeto que estou desenvolvendo.


por: douglas_fc (douglasfc@grupocarvalho.com.br) : Jan 21, 2013 - 12:39
(Informações sobre o membro | Enviar uma mensagem) http://
exelente artigo parabéns!!


por: rbarbosa (rui.barbosa@infonet.com.br) : Jan 25, 2013 - 07:35
(Informações sobre o membro | Enviar uma mensagem) http://
Olá amigo!
muito bom seu exemplo, gostaria de saber se é possivel o grid ficar nas duas condições, zebrado e linha destacado. tenha um otimo dia.
  Edição 112

Revista ActiveDelphi

  50 Programas Fontes


  Produtos

Conheça Nossos Produtos

Copyright© 2001-2016 – Active Delphi – Todos os direitos reservados