Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Linien im StringGrid zeichnen Ohne OnDrawCell (https://www.delphipraxis.net/115695-linien-im-stringgrid-zeichnen-ohne-ondrawcell.html)

SaFu 16. Jun 2008 14:01


Linien im StringGrid zeichnen Ohne OnDrawCell
 
Tag

Folgendes ich versuche die Linen im StringGrid nicht im OnDrwa Ereignis zu zeichnen sondern im Button geht das Irgenwie

weil wenn sich meine überschrift im Label ändert sollen andere linien gezeichnet werden.

Im Button gehts nicht nicht im OnDrawCell ja

Delphi-Quellcode:
procedure TForm7.Button1Click(Sender: TObject);
Var n :integer;
begin
if Label3.Caption = 'Arbeitszeit' then
 begin //Linien zwischen Zellen erzeugen
 n:= 0;
  repeat
   n:= n + 4;
    if (StringGrid1.Row = n) and (StringGrid1.Col >= StringGrid1.FixedCols) then
     begin
      StringGrid1.Canvas.Pen.Color := clBlack; // Linienfarbe
      StringGrid1.Canvas.Pen.Width := 2; // Stärkt der Linie
      StringGrid1.Canvas.MoveTo(Rect.Left,Rect.Bottom);
      StringGrid1.Canvas.LineTo(Rect.Right,Rect.Bottom);
     end;
  until n= 24;
 end;

 // zellen verbinden für Spalte 0
  if (StringGrid1.Col = 0) And (StringGrid1.Row In [1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 23]) then
   begin
    StringGrid1.Canvas.Pen.Color := clWhite;
    StringGrid1.Canvas.Pen.Width := 2;
    StringGrid1.Canvas.MoveTo(Rect.Left, Rect.Bottom);
    StringGrid1.Canvas.LineTo(Rect.Right, Rect.Bottom);
   end;

 // Liene neben der klasse erzeugen
 if (StringGrid1.Col = 1) And (StringGrid1.Row In [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]) then
  begin
   StringGrid1.Canvas.Pen.Color := clBlack;
   StringGrid1.Canvas.Pen.Width := 1;
   StringGrid1.Canvas.MoveTo(Rect.Right, Rect.Top);
   StringGrid1.Canvas.LineTo(Rect.Right, Rect.Bottom);
  end;
 end;
end;
hoffe mir kann jemand helfen


Gruß Sascha

mkinzler 16. Jun 2008 14:21

Re: Linien im StringGrid zeichnen Ohne OnDrawCell
 
Das Problem ist das wen das Grid neu gezeichnet wird, deine manuell gezeichnete Grafik verschwindet.

SaFu 16. Jun 2008 14:23

Re: Linien im StringGrid zeichnen Ohne OnDrawCell
 
Also geht es nicht oder wie verstehe ich das

Larsi 16. Jun 2008 14:25

Re: Linien im StringGrid zeichnen Ohne OnDrawCell
 
Du müsstest halt darauf reagieren wenn sich das Stringgrid neuzeichnet, bzw. dann die OnClick Funktion aufrufen.

DP-Maintenance 16. Jun 2008 15:52

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "VCL / WinForms / Controls" verschoben.
TStringGrid -> VCL

shmia 16. Jun 2008 15:56

Re: Linien im StringGrid zeichnen Ohne OnDrawCell
 
Also mal grundsätzlich gilt: gezeichnet wird nur im Event OnDrawCell!
Wenn du möchtest, dass dein Stringgrid sich auf Kopfdruck optisch verändert, dann gibt es keine andere Möglichkeit, als die Information, WIE gezeichnet werden soll in einer Variablen (*) abzulegen und dann StringGrid.Invalidate aufzurufen.

*) man kann diese Information auch in den Zellen des StringGrids selbst unterbringen.

raiguen 16. Jun 2008 18:34

Re: Linien im StringGrid zeichnen Ohne OnDrawCell
 
Zitat:

Zitat von shmia
Also mal grundsätzlich gilt: gezeichnet wird nur im Event OnDrawCell!...

Als Tipp habe ich deine Routine mal etwas abgeändert und flotter gemacht ;)
Delphi-Quellcode:
procedure TfrmZaehlerStaende.StringGrid1DrawCell(Sender: TObject; ACol,
  ARow: Integer; Rect: TRect; State: TGridDrawState);
Var sgc: TCanvas;
begin
  //--nicht unbedingt notwendig, aber wenn man Schreibfaul ist,nimmt man halt ne sinnvolle Abkürzung ;)
  sgc := StringGrid1.Canvas;

  if Label3.Caption = 'Arbeitszeit' then
     //Linien zwischen Zellen erzeugen
     if (ARow mod 4 = 0) and (ACol >= StringGrid1.FixedCols) then
       begin
        sgc.Pen.Color := clred; // Linienfarbe
        sgc.Pen.Width := 2; // Stärkt der Linie
        sgc.MoveTo(Rect.Left,Rect.Bottom);
        sgc.LineTo(Rect.Right,Rect.Bottom);
       end;
 

  // zellen verbinden für Spalte 0
  if (ACol = 0) And not (ARow In [4,8,12,16,20,24]) then
   begin
    sgc.Pen.Color := clgreen;
    sgc.Pen.Width := 2;
    sgc.MoveTo(Rect.Left, Rect.Bottom);
    sgc.LineTo(Rect.Right, Rect.Bottom);
   end;

  // Linie neben der klasse erzeugen
  if (ACol = 1) And (ARow In [1..23]) then
    begin
     sgc.Pen.Color := clfuchsia;
     sgc.Pen.Width := 1;
     sgc.MoveTo(Rect.Right, Rect.Top);
     sgc.LineTo(Rect.Right, Rect.Bottom);
    end;
end;
Okay, die merkwürdigen Farben hab ich nur für mich zum Test und besseren Erkennen eingesetzt.
Zitat:

repeat
n:= n + 4;
if (StringGrid1.Row = n) and (StringGrid1.Col >= StringGrid1.FixedCols) then
begin
...
end;
until n= 24;
ist gaaaaanz schlecht(er Stil), weil: diese Schleife wird beim Zeichnen JEDER(!!) Zelle durchlaufen und verlangsamt das Ganze und kann auch teilweise zu merkwürdigen Zeichenverhalten beim Scrollen führen.
Delphi-Quellcode:
 ARow mod 4 = 0
heisst vereinfacht: wenn die Zeilennummer glatt durch 4 teilbar ist (also Rest=0) dann pinsel den entsprechenden Strich...(also Zeilennr 4,8,12,...)
und das hier
Delphi-Quellcode:
not (ARow In [4,8,12,16,20,24])
ist eine andere Möglichkeit, alle 4-er-Zeilen entsprechend zu behandeln ;) (in diesem Fall eben diese Zeilen überspringen...)
wenn man das Ganze noch mehr vereinfachen will kann man statt dessen auch diese beiden Möglichkeiten nehmen:
Delphi-Quellcode:
not (ARow mod 4 = 0) oder (ARow mod 4 <> 0)
Das nur so als gut gemeinter Tipp am Rande :lol:

shmia 16. Jun 2008 18:36

Re: Linien im StringGrid zeichnen Ohne OnDrawCell
 
Hier ein Beispiel, wie man rote und grüne Rähmchen im Grid zeichnet.
In den Options sind die Flag goVertline und goHorLine auf False gestellt.
Delphi-Quellcode:
var
   Zeile : integer = 1;
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
   canvas : TCanvas;
begin
   canvas := Stringgrid1.canvas;

   // Textausgabe
   Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2, StringGrid1.Cells[ACol, ARow]);

   if (ARow = Zeile) and (ACol >= 1) then // nur in der best. Zeile
   begin
      if (ACol mod 2) = 0 then
         canvas.Pen.Color := clRed
      else
         canvas.Pen.Color := clGreen;

      canvas.Brush.Style := bsClear;
      InflateRect(Rect, 1, 1); // Rechteck um 1 Pixel grösser machen
      canvas.Rectangle(rect);  // Rähmchen malen
   end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
   Inc(zeile);  
   StringGrid1.Invalidate;  // StringGrid soll neu gezeichnet werden
end;
Das Beispiel hat noch ein kleines Problem: InflateRect() vergrössert das Rechteck in nach links, rechts, oben und unten. Dabei kommt es zu Überschneidungen. Wenn man das nicht mag, muss man InflateRect durch etwas anderes ersetzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz