String Grid Canvas

Delphi

20/06/2006

Boa Tarde a Todos!

Estive pesquisando no forum sobre o canvas e o String Grid e consegui fazer algo parecido com o que eu preciso, no caso estou precisando que o String Grid verifique um valor numa celular e conforme esse valor mude a cor da linha, segue abaixo o codigo no evendo DrawCell do String Grid

  If Grade.Cells[0,Arow] = ´X´ Then
    Grade.Canvas.Brush.Color:= clYellow
  Else
    Grade.Canvas.Brush.Color:= clWindow;
  If ARow = 0 Then// para o titulo
    Grade.Canvas.Brush.Color:= clBtnFace;
  Grade.Canvas.FillRect(Rect);
  Grade.Canvas.TextRect(Rect,Rect.Left,Rect.Top,Grade.Cells[ACol,ARow]);


com esse codigo quando eu marco uma celula( ex.: cells[0,1] com o valor de ´X´ o sistema marca somente a celula com o ´X´ as demais celulas da linha ficam em branco. Estou precisando q quando a Cell[0,1] for Marcado fique toda a linha selecionada.

Para Marca a celula estou usando o evento onClick do String Grid:

  If Grade.Cells[0,Grade.Row] = ´´ Then
    begin
      Grade.Cells[0,Grade.Row]:= ´X´
    end
  Else
    Grade.Cells[0,Grade.Row]:= ´´;



Agradeço desde ja a atenção


Ednet

Ednet

Curtidas 0

Respostas

Rodc

Rodc

20/06/2006

Coloque no final do evento OnClick este código:
Grade.Repaint();

Depois avisa se era isto que você queria.


GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

Porque quando utilizamos esse evento para mudança de cor da string grid ela fica piscando e mais lenta?


GOSTEI 0
Rodc

Rodc

20/06/2006

Porque quando utilizamos esse evento para mudança de cor da string grid ela fica piscando e mais lenta?

Porque ele gasta tempo repintando todo o Grid toda vês que você fizer alguma alteração no Grid.
Para ´suavizar´ o problema, coloque a opção DoubleBuffered do Grid para true. Isto fará com que o componente seja pintado primeiramente em memória e depois copiado para o Canvas.


GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

eu nao tenho esta opcao aki


GOSTEI 0
Rodc

Rodc

20/06/2006

eu nao tenho esta opcao aki

Esta opção está em runtime. Ela não fica no ObjectInspector.


GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

ok obrigado ja encontrei e coloquei no evento OnDrawCell


GOSTEI 0
Rodc

Rodc

20/06/2006

ok obrigado ja encontrei e coloquei no evento OnDrawCell

O código ´Grid.DoubleBuffered := true´ não precisa ficar no OnDrawCell. Coloca ele no OnCreate do Form.


GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

Bom dia,

Utilizei a solução proposta, porém essa solução deixou a aplicação lenta, alguem sabe me dizer porque? utilizei a opcao DoubleBuffered mas mesmo assim, os botões demoram para ser carregados.


GOSTEI 0
Rodc

Rodc

20/06/2006

Bom dia, Utilizei a solução proposta, porém essa solução deixou a aplicação lenta, alguem sabe me dizer porque? utilizei a opcao DoubleBuffered mas mesmo assim, os botões demoram para ser carregados.

É que, pelo desenho do Canvas ser feito primeiramente em memória, consome mais memória e processamento. Pelo conhecimento que tenho, não tem como fugir deste problema. Apenas verifique se a rotina que altera o Canvas não está entrando em recursividade ou muitas vezes seguidamente. Analise uma forma de reduzir o desenho do Canvas.


GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

o problema é realmente este se vc resolve debugar a aplicação ele só fica dentro da rotina, e a rotina eu fiz desta forma:

procedure TfrmProtocolos.tblItemDrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
If (tblItem.Cells[7, ARow] <> ´´) AND (tblItem.Cells[7, ARow] <> ´__/__/____´) AND
(tblItem.Cells[7, ARow] <> ´ / / ´) AND (tblItem.Cells[7, ARow] <> ´Dta. pagto.´) Then
Begin
tblItem.Font.Color := clRed;
End
Else
tblItem.Font.Color := clBlack;
end;

onde esta o problema?


GOSTEI 0
Rodc

Rodc

20/06/2006

onde esta o problema?

Aparentemente não tem problema. Talvêz sua máquina seja muito lenta. Para verificar a quantidade de vezes que o código é executado, coloque a linha abaixo dentro do código Draw e verifique no Caption do form os números aumentando.

Caption := StrToIntDef(Caption, 0) + 1;


GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

Impossível ser a maquina lenta é um notebook satellite P4 HT de 3.2Ghz, 512Mb de memória.

Ele passa mais ou menos umas 20 mil vezes nesse código, porque tanto assim?


GOSTEI 0
Rodc

Rodc

20/06/2006

Afff!! 20mil vezes? É muita coisa....
Tenta trocar usando o canvas, por exempo:
tblItem.Canvas.Pen.Color := clRed



GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

mas este problema de o nro de vezes nao esta na procedure?


GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

com o Canvas ele nao muda a cor da fonte do item, porque?


GOSTEI 0
Rodc

Rodc

20/06/2006

mas este problema de o nro de vezes nao esta na procedure?

É que toda vêz que você altera a cor da fonte o componente chama o draw novamente, e assim fica sempre em loop.
Tem que tentar alterar a cor da fonte de outra forma, talvêz usar um outro evento OnDraw´qualquer_coisa´, ou desenhar o texto direto no canvas com a função Canvas.TextOut().


GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

bom essa string grid é um componente e chama-se TAdvStringGrid, porque que o canvas nao funciona com ele?

se eu mudo para tblItem.Font.Color ele aumenta muito o nro de vezes porem se coloco o canvas passa bem menos


GOSTEI 0
Rodc

Rodc

20/06/2006

Muito bem usei o código abaixo em um TStringGrid nomeado de grid. Tenta no seu componente:
procedure TForm1.GridDrawCell(SenderTObject, ACol: int , ARow: int, &Rect: TRect, State: TGridDrawState)
begin
    if (ACol = 2)
    begin
        Grid.Canvas.Font.Color := clRed;
        Grid.Canvas.TextOut(Rect.Left+2, Rect.Top+2, Grid.Cells[ACol][ARow]);
        Grid.Canvas.Font.Color := clBlack;
    end;

    Caption := StrToIntDef(Caption, 0) + 1;
end;



GOSTEI 0
Dcpleal

Dcpleal

20/06/2006

Bom dia,

A uns dias fui ajudado quando a situação de mudar a cor da fonte quando uma determinada situação acontecia, porém tenho o costume de alinhas os campos da string grid da seguinte forma: campos alfanumericos a esquerda, campos de data ao centro e campos de valores numéricos ou inteiros à direita, o problema que ocorre é o seguinte para os campos alfanumericos e data deu tudo certo quanto a cor, o problema esta sendo para os campos numéricos ou inteiros, como coloco da direita para esquerda nao estou conseguindo colocar a cor no local certo, pois fica tudo misturado seguindo a idéia que foi proposta.

alguem poderia me ajudar?

agradeço

Danilo


GOSTEI 0
Wellington Telles

Wellington Telles

20/06/2006

Fiz em Delphi com FMX:

procedure TFormMain.StringGrid1DrawColumnCell(Sender: TObject;
  const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF;
  const Row: Integer; const Value: TValue; const State: TGridDrawStates);
var
  RowColor : TBrush;
begin
  RowColor := Tbrush.Create(TBrushKind.Solid,TAlphaColors.Alpha);
  if (Sender as TStringGrid).Cells[2, Row] = 'NOK' then
  begin
     RowColor.Color := TAlphaColors.Red;
     Canvas.FillRect(Bounds, 0, 0, [], 1, RowColor);
  end;
  if (Sender as TStringGrid).Cells[2, Row] = 'OK' then
  begin
     RowColor.Color := TAlphaColors.Lime;
     Canvas.FillRect(Bounds, 0, 0, [], 1, RowColor);
  end;
  Column.DefaultDrawCell(Canvas, Bounds, Row, '', State);
  Canvas.Font.Size := 20;
  Canvas.Fill.Color := TAlphaColorRec.Black;
  Canvas.FillText(Bounds,(Sender as TStringGrid).Cells[Column.Index, Row],False,1,[], TTextAlign.Center);
  RowColor.Free;
end;
GOSTEI 0
POSTAR