Você está na página 1de 7

07/08/13

Dicas sobre o componente DBGrid do Delphi | Diego Garcia

Dicas sobre o componente DBGrid do Delphi


Publicado em 17/01/2013

O Dbgrid talvez seja um dos componentes mais utilizados no dia a dia de um desenvolvedor delphi, principalmente em solues comerciais, isso graas ao fato de que o uso deste componente seja definitivamente a maneira mais simples e mais rpida de apresentar dados de um dataSet para o usurio, seja esse dataSet o resultado de uma pesquisa em um banco de dados, registros temporrios, etc. Na grande realidade o conceito de grid est presente em qualquer ambiente de desenvolvimento. Neste post eu resolvi juntar algumas dicas simples e prticas para melhorar a utilizao deste componente. Para melhor demonstrar os resultados dos exemplos, criei um projeto teste com dados fictcios em um ClienteDataSet, porem, os exemplos que fiz so quase que 100% independentes do tipo de dataSet utilizado. Fazer linha zebrada: vamos usar a lgica mais utilizada para zebrar linhas em um grid, verificar se o numero do registro atual do dataSet impar ou par, veja que no estou falando do valor de algum campo do dataSet, mas sim o numero da linha dentro do dataSet. Para recuperar essa informao, 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 mtodo 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 so desenhados no grid. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4
p r o c e d u r eT F o r m 1 . D B G r i d 1 D r a w C o l u m n C e l l ( S e n d e r :T O b j e c t ;c o n s tR e c t :T R e c t ; D a t a C o l :I n t e g e r ;C o l u m n :T C o l u m n ;S t a t e :T G r i d D r a w S t a t e ) ; b e g i n w i t hD B G r i d 1d o b e g i n i fO d d (D a t a S o u r c e . D a t a S e t . R e c N o )t h e n C a n v a s . B r u s h . C o l o r: =c l S i l v e r e l s e C a n v a s . B r u s h . C o l o r: =c l M o n e y G r e e n ; C a n v a s . F i l l R e c t ( R e c t ) ; D e f a u l t D r a w C o l u m n C e l l ( R e c t , D a t a C o l , C o l u m n , S t a t e ) ; e n d ; e n d ;

Note que para customizar a visualizao do meu grid, eu utilizei a propriedade Canvas, nesta propriedade que ficam as configuraes 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
drgarcia1986.wordpress.com/2013/01/17/dicas-sobre-o-componente-dbgrid-do-delphi/ 1/7

07/08/13

Dicas sobre o componente DBGrid do Delphi | Diego Garcia

Destacar linhas: Muitas vezes precisamos dar algum destaque visual para determinados registros dependendo de alguma condio, para isso, podemos alterar dinamicamente a formatao 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 no selecionados fiquem com a fonte vermelha e em negrito. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9
p r o c e d u r eT F o r m 1 . D B G r i d 1 D r a w C o l u m n C e l l ( S e n d e r :T O b j e c t ;c o n s tR e c t :T R e c t ; D a t a C o l :I n t e g e r ;C o l u m n :T C o l u m n ;S t a t e :T G r i d D r a w S t a t e ) ; b e g i n w i t hD B G r i d 1d o b e g i n i fD a t a S o u r c e . D a t a S e t . F i e l d B y N a m e ( ' s a l a r i o ' ) . A s F l o a t>2 5 0 0t h e n b e g i n i f( g d S e l e c t e di nS t a t e )t h e n C a n v a s . B r u s h . C o l o r: =c l R e d e l s e b e g i n C a n v a s . F o n t . S t y l e: =[ f s B o l d ] ; C a n v a s . F o n t . C o l o r: =c l R e d ; e n d e n d ; C a n v a s . F i l l R e c t ( R e c t ) ; D e f a u l t D r a w C o l u m n C e l l ( R e c t , D a t a C o l , C o l u m n , S t a t e ) ; e n d ; e n d ;

Comparando com o exemplo anterior no temos muitas diferenas, a no ser pela verificao gdSelected in State, caso esta verificao resulte em true significa que neste momento o DBGrid est desenhando a linha selecionada. Neste o exemplo, o resultado ficaria desta forma

Destacar uma clula e uma coluna: Este exemplo, no chega a ser muito diferente do anterior, por isso, mantive a mesma lgica, a coluna referente ao camposalario ficar
drgarcia1986.wordpress.com/2013/01/17/dicas-sobre-o-componente-dbgrid-do-delphi/ 2/7

07/08/13

Dicas sobre o componente DBGrid do Delphi | Diego Garcia

com o fundo cinza, porem, caso algum registro tenha uma valor neste campo maior do que 2500, a clula ficar com o fundo vermelho e a fonte amarela. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8
p r o c e d u r eT f r m P r i n c i p a l . D B G r i d 1 D r a w C o l u m n C e l l ( S e n d e r :T O b j e c t ; c o n s tR e c t :T R e c t ;D a t a C o l :I n t e g e r ;C o l u m n :T C o l u m n ;S t a t e :T G r i d D r a w S t a t e ) ; b e g i n w i t hD B G r i d 1d o b e g i n i fA n s i L o w e r C a s e ( C o l u m n . F i e l d N a m e )=' s a l a r i o 't h e n b e g i n C a n v a s . B r u s h . C o l o r: =c l S i l v e r ; i fC o l u m n . F i e l d . A s F l o a t>2 5 0 0t h e n b e g i n C a n v a s . B r u s h . C o l o r: =c l R e d ; C a n v a s . F o n t . C o l o r : =c l Y e l l o w ; e n d ; e n d ; C a n v a s . F i l l R e c t ( R e c t ) ; D e f a u l t D r a w C o l u m n C e l l ( R e c t , D a t a C o l , C o l u m n , S t a t e ) ; e n d ; e n d ;

Talvez a diferena mais importante entre este exemplo e o anterior a verificao feita pela coluna, ou seja, a manipulao do canvas feita somente quando a coluna salario est sendo desenhada. Rodando esse exemplo em nossa base de estudo, teramos 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. 1 2 3 4 5 6 7 8
p r o c e d u r eT F o r m 1 . D B G r i d 1 D r a w C o l u m n C e l l ( S e n d e r :T O b j e c t ;c o n s tR e c t :T R e c t ; D a t a C o l :I n t e g e r ;C o l u m n :T C o l u m n ;S t a t e :T G r i d D r a w S t a t e ) ; c o n s t I S _ C H E C K:A r r a y [ B o o l e a n ]o fI n t e g e r =( D F C S _ B U T T O N C H E C K ,D F C S _ B U T T O N C H E C K v a r C h e c k:I n t e g e r ; R :T R e c t ; b e g i n w i t hD B G r i d 1d o
3/7

drgarcia1986.wordpress.com/2013/01/17/dicas-sobre-o-componente-dbgrid-do-delphi/

07/08/13

Dicas sobre o componente DBGrid do Delphi | Diego Garcia

9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0

b e g i n i fA n s i L o w e r C a s e ( C o l u m n . F i e l d N a m e )=' s e l e c i o n a d o 't h e n b e g i n C a n v a s . F i l l R e c t ( R e c t ) ; C h e c k: =I S _ C H E C K [ C o l u m n . F i e l d . A s B o o l e a n ] ; R: =R e c t ; I n f l a t e R e c t ( R , 2 , 2 ) ;/ / a q u im a n i p u l aot a m a n h od oc h e c k B o x D r a w F r a m e C o n t r o l ( C a n v a s . H a n d l e , r e c t , D F C _ B U T T O N , C h e c k ) e n d ; e n d ; e n d ;

O cdigo 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 questo, atravs da varivel Check , o resultado deste exemplo ficaria desta forma

Para deixar um pouco mais prtico o uso do checkBox no DBgrid, podemos fazer uma rotina para marcar ou desmarcar o componente quando a clula que ele est seja clicada 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2

p r o c e d u r eT F o r m 1 . D B G r i d 1 C e l l C l i c k ( C o l u m n :T C o l u m n ) ; b e g i n i fC o l u m n . F i e l d . F i e l d N a m e=A n s i L o w e r C a s e ( ' s e l e c i o n a d o ' )t h e n b e g i n w i t hD B G r i d 1 . D a t a S o u r c e . D a t a S e td o b e g i n e d i t ; F i e l d B y N a m e ( ' s e l e c i o n a d o ' ) . V a l u e: =n o tF i e l d B y N a m e ( ' s e l e c i o n a d o ' ) . A s B o o l e a P o s t ; e n d ; e n d ; e n d ;

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
drgarcia1986.wordpress.com/2013/01/17/dicas-sobre-o-componente-dbgrid-do-delphi/ 4/7

07/08/13

Dicas sobre o componente DBGrid do Delphi | Diego Garcia

com o ndice 1

Agora basta desenhar as imagens no DBGrid de acordo com a coluna e o valor da coluna. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2

p r o c e d u r eT F o r m 1 . D B G r i d 1 D r a w C o l u m n C e l l ( S e n d e r :T O b j e c t ;c o n s tR e c t :T R e c t ; D a t a C o l :I n t e g e r ;C o l u m n :T C o l u m n ;S t a t e :T G r i d D r a w S t a t e ) ; b e g i n w i t hD B G r i d 1d o b e g i n i fA n s i L o w e r C a s e ( C o l u m n . F i e l d N a m e )=' s e l e c i o n a d o 't h e n b e g i n C a n v a s . F i l l R e c t ( R e c t ) ; I m a g e L i s t 1 . D r a w ( C a n v a s , R e c t . L e f t + 1 0 , R e c t . T o p + 1 , O r d ( C o l u m n . F i e l d . A s B o o l e a n ) ) e n d ; e n d ; e n d ;

Simples no? At mais simples do que o checkBox, apesar de nem sempre deixar o visual mais profissional.

Utilizar um ComboBox em uma coluna: A tcnica de utilizar um ComboBox em um grid feita de uma forma um pouco diferente dos exemplos anteriores, dentro dasColumns do Dbgrid existe a propriedade PickList que consiste em um objeto do
drgarcia1986.wordpress.com/2013/01/17/dicas-sobre-o-componente-dbgrid-do-delphi/ 5/7

07/08/13

Dicas sobre o componente DBGrid do Delphi | Diego Garcia

tipoTStrings e utilizado exatamente para dar esse efeito do combo dentro de uma clula do grid. Ento para demonstrar a utilizao desta propriedade, dentro do meu mtodo de carregar os dados, eu coloquei o seguinte trecho de cdigo: 1 2 3 4 5 6 7 8
w i t hD b g r i d 1 . C o l u m n s [ 2 ] . P i c k L i s td o/ / c o l u n ar e f e r e n t ea oc a r g o b e g i n C l e a r ; A d d ( ' G E R E N T E ' ) ; A d d ( ' R E P R E S E N T A N T E ' ) ; A d d ( ' E N C A N A D O R ' ) ; A d d ( ' V E N D E D O R ' ) ; e n d ;

Obviamente este apenas um exemplo didtico, em uma situao real poderamos carregar esta propriedade com valores vindos de uma tabela de validao por exemplo. O cdigo acima daria o seguinte efeito:

Ordenar dinamicamente pela coluna clicada pelo usurio: Por experiencia eu digo que a ordenao dos dados em um DBgrid uma das coisas mais importantes na hora de apresentar dados para um usurio, mas normal surgir a pergunta, como saber por qual campo ordenar os dados? Simples, permita que o usurio escolha por qual campo ele quer fazer a ordenao. Pode parecer que no, mas algo simples, neste exemplo faremos com que quando o usurio clique no titulo de uma coluna no DBgrid, este seja ordenado pelo campo desta coluna. Para deixar mais intuitivo para o usurio, vamos mudar o icone do mouse quando este estivar passando pelo titulo dos campos no DBGrid, atravs do mtodo OnMouseMove 1 2 3 4 5 6 7 8 9 1 0 1 1
p r o c e d u r eT F o r m 1 . D B G r i d 1 M o u s e M o v e ( S e n d e r :T O b j e c t ; S h i f t :T S h i f t S t a t e ;X ,Y :I n t e g e r ) ; v a r m o u s e P t :T G r i d c o o r d ; b e g i n m o u s e P t: =D b G r i d 1 . M o u s e C o o r d ( x , y ) ; i fm o u s e P t . y=0 t h e n S c r e e n . C u r s o r: =c r H a n d P o i n t e l s e S c r e e n . C u r s o r: =c r D e f a u l t ; e n d ;

drgarcia1986.wordpress.com/2013/01/17/dicas-sobre-o-componente-dbgrid-do-delphi/

6/7

07/08/13

Dicas sobre o componente DBGrid do Delphi | Diego Garcia

Esse mtodo 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, teramos os seguintes valores no TGridcoord.Y e TGridcoord.X 1 2
Y=2 ; X=3 ;

Agora vamos efetivamente fazer a ordenao dos dados. Para deixar um pouco mais visual, vamos tambm deixar em negrito o titulo da coluna em que o DBgrid est ordenado. A ordenao dos dados com clientDataSet fica fcil graas a propriedade IndexFieldNamesque define por quais campos o clientDataSet ser indexado. Sendo assim no mtodoOnTitleClick , basta colocar o seguinte cdigo: 1 2 3 4 5 6 7 8 9
p r o c e d u r eT F o r m 1 . D B G r i d 1 T i t l e C l i c k ( C o l u m n :T C o l u m n ) ; v a r I :I n t e g e r ; b e g i n f o r I: =0 t oD B G r i d 1 . C o l u m n s . C o u n t-1 d o D B G r i d 1 . C o l u m n s [ i ] . T i t l e . F o n t . S t y l e: =[ ] ; T C l i e n t D a t a S e t ( D B G r i d 1 . D a t a S o u r c e . D a t a S e t ) . I n d e x F i e l d N a m e s: =C o l u m n . F i e l d N a m e ; C o l u m n . T i t l e . F o n t . S t y l e: =[ f s B o l d ] ; e n d ;

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

Talvez este seja o nico exemplo que faa com as dicas deste post no sejam 100% compatveis com qualquer dataSet, pois utilizamos um mtodo prprio de ClientDataSets, porem isso no significa que no seja possvel fazer este exemplo com outros tipos de dataSets, basta fazer uma ou outra adaptao.

drgarcia1986.wordpress.com/2013/01/17/dicas-sobre-o-componente-dbgrid-do-delphi/

7/7

Você também pode gostar