Autor Beitrag
D. Annies
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Fr 17.06.05 18:17 
Hi, Delpher,

ich habe ein Stringgrid mit 24 Spalten und 30 Zeilen, die ersten drei Spalten und die erste Zeile sind fixed.

"Innen" befinden sich Daten. Gibt es eine Möglichkeit, dass, wenn in einer (jeder) Zeile (> 1) alle Zellen (> 3) leer sind, z.B. die zweite Zelle dieser (jeder) Zeile grün gefärbt wird??

Ich hab es [ohne Erfolg] mit OndrawCell versucht, es wird auch klaglos kompiliert, aber nicht gefärbt.

Wie kann dazu ein CodeSchnipsel aussehen?

Vielen Dank für eure Hilfe,
D. Annies
toms
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1099
Erhaltene Danke: 2



BeitragVerfasst: Sa 18.06.05 10:07 
Hallo,

Wie sieht denn dein bisheriger Codeschnipsel aus?
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Sa 18.06.05 22:10 
Hi, toms,

danke für deine Nachfrage. Hoffentlich fällst du nicht in Ohnmacht, bzw. der Code ist einigermaßen verständlich. Aber es ist jetzt wie ein Spielautomat, es flackert dauern, weil ja Ondrawcell ständig aktualisiert.

Geht es mit Repaint? (wie?)


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
procedure sg9green(sender:tobject);
var n, k : integer;
begin
  k := 1; gr := true;
  repeat
    n := 3;
    repeat
      if form1.stringgrid9.cells[n,k] <> '' then gr := false;  inc(n);
    until not gr or (n = form1.stringgrid9.colcount-2);
    if not gr then
    begin
      form1.stringgrid9.cells[0,k] := form1.stringgrid9.cells[0,k]+' ';
      gr := true;
    end;
    inc(k);
  until not gr or (k = form1.stringgrid9.rowcount-1);
end;

procedure TForm1.stringgrid9DrawCell(Sender: TObject; aCol, aRow: Longint; Rect: TRect; State: TGridDrawState);
begin
  sg9green(self); //if gr = true then showmessage('1') else showmessage('0');
  with Tstringgrid(Sender), Canvas do
  begin
    //if gr = true then showmessage('1') else showmessage('0');  //if gdfixed in state then exit;
    if acol > 2 then
    begin
      if cells[acol, arow] <> '' then  brush.color := clgray
      else  brush.color := clwindow;
      fillrect(rect);
      textout(rect.left+2, rect.top+2, cells[acol, arow]);
    end;
    if arow = 0 then
    begin
      brush.color := clbtnface; fillrect(rect);
      textout(rect.left+2, rect.top+2, cells[acol, arow]);
    end;
    if (acol = 0and (arow > 0and gr then
    begin
      brush.color := clred;
      textout(rect.left+2, rect.top+2, cells[acol, arow]);   gr := false;
    end;
    if (acol = 0and (arow > 0and not gr then
    begin
      brush.color := clbtnface;
      textout(rect.left+2, rect.top+2, cells[acol, arow]);   gr := true;
    end;
  end;
end;


Moderiert von user profile iconChristian S.: Delphi-Tag repariert
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Sa 18.06.05 22:51 
Am OnDrawCell führt kein Weg vorbei ! Weil dein Source nicht formatiert ist, sehe ich allerdings nicht genau woran es hängt. Hier ist ein (gekürtzter) Codeschnipsel :

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure Tfrm.sgDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  inherited;
  if (ARow >= sgArtNr.FixedRows) and (ACol >= sgArtNr.FixedCols) then begin
blabla
    else if (ACol in ZahlenCols) then with Sender as TStringGrid do begin
      if (ACol = 1then begin
            canvas.Font.Name := 'Arial';
            canvas.Font.Size:=8;
            canvas.Font.Color:=clwhite;
            canvas.brush.Color := clBlack;
            canvas.TextOut(rect.Left,
                           rect.bottom-canvas.Textheight('TEST')-1,
                           ' TEST ');


So ungefähr geht das.

Edit : aha Quelltext repariert ? :lol: Da fällt mir dann noch das hier auf :
sg9green(self); Was ist das ?

_________________
Gruß
Hansa
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: So 19.06.05 01:06 
Hi, Hansa,

green() soll in jeder Stringgridzeile prüfen, ob sie leer ist. Bei mindestens einem Eintrag soll die jeweils zweite Spalte grün gefärbt werden.

P.S. Kannst du mir noch einmal genau sagen, wie ich die Delphi-Tags setze? Mir ist mal gesagt worden: ecige Klammer auf, Slash, Delphi dann der Code und zum Schluss
Eckige Klammer auf, Leertaste, Slash, Delphi.
Habe ich da was verpeilt? :oops:

Danke für Hilfe,
Detlef Annies
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: So 19.06.05 01:38 
Die Leerzeichen werden die Schuld haben. Zum Thema : auch hier Leerzeichen !

_________________
Gruß
Hansa
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: So 19.06.05 01:51 
Hi, Hansa,

Leider nein (mit den Leertasten). Damit wollte ich den Neuaufbau nur ein bisschen beschäftigen, denn ohne Leerzeichen ist nur noch ein mattes Flimmern zu sehen, mit Leerzeichen eine deutliche, aber auch flimmernde Markierung(Farbänderung).

CU, D. Annies
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: So 19.06.05 02:08 
Du mußt die Zellen abfragen. Wird das nicht gemacht, dann "flackert" es. Also Cols und Rows abfragen.

_________________
Gruß
Hansa
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: So 19.06.05 10:20 
Hi, Hansa!

Leider kenne ich keine Möglichkeit, anders als in meinem obigen Code die cols oder rows abzufragen, kannst du mir da weiterhelfen?

Wäre nett, D. Annies
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 19.06.05 12:13 
@D. Annies

in deinem code sehe ich nicht durch, für was soll sggreen gut sein? du hast zwar
Zitat:

green() soll in jeder Stringgridzeile prüfen, ob sie leer ist. Bei mindestens einem Eintrag soll die jeweils zweite Spalte grün gefärbt werden.

geschrieben, das ist auch nur eine prozedur, keine function? globale Varibalen sind meistens unnötig.

Außerdem: innerhalb von sggrenn änderst du die Zellen. Damit werden die neugezeichnet und wieder ondrawcell aufgerufen, dort dann wieder sggreen. Du hängst dann auch in einer endlosschleife, kein wunder, das es flackert.

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: So 19.06.05 13:17 
Hi, Keldorn,

Besteht denn eine Chance, die Endlosschleife zu vermeiden, wenn ich die Repeat-Schleifen in OnDrawCell setze?

Diese sollen ja sicherstellen, dass der Datenbereich(col > 3 und row > 0) jeweils zeilenweise leer ist.

Bis bald? :?

D. Annies
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 19.06.05 13:50 
user profile iconD. Annies hat folgendes geschrieben:


Besteht denn eine Chance, die Endlosschleife zu vermeiden, wenn ich die Repeat-Schleifen in OnDrawCell setze?

nein. Eine Schleife hat im ondrawcell nichts zu suchen. Ondrawcell wird immer aufgerufen, wenn eine Zelle neugezeichnet werden muß.

anhand von deinem ersten post:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
procedure TForm1.FormCreate(Sender: TObject);
begin
  with StringGrid1 do
    begin
      rowcount:=30;
      colcount:=24;
      FixedRows:=1;
      FixedCols:=3;
    end;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;Rect: TRect; State: TGridDrawState);

  function ZeileIstLeer(Grid:TStringGrid;Zeile:integer):boolean;
  Var i:integer;
    begin
      result:=true;
      with grid do
        begin
          for i:=FixedCols to ColCount-1 do
            begin
              //evtl noch ein trim mit rtein, damit Leerzeichen nicht unerkannt bleiben
              if cells[i,Zeile]<>'' then
                begin
                  result:=false;
                  break;
                end;
            end;
        end;
    end;

begin
  //keine fixierten Zellen
  if gdfixed in state then exit;
  with sender as TStringGrid do
    begin
      //Farben entsprechend setzen
      if ZeileIstLeer(Sender as TStringGrid,arow) then
        begin
          //quote: wenn in einer (jeder) Zeile (> 1) alle Zellen (> 3) leer sind,
          //z.B. die zweite Zelle dieser (jeder) Zeile grün gefärbt wird??
          if not(odd(acol)) then canvas.Brush.color:=clgreen
                            else canvas.Brush.color:=clwindow;
        end
       else
        begin
          //sonst ganz normal zeichnen
          if gdselected in state then
            begin
              canvas.Brush.Color:=clHighlight;
              canvas.Font.Color :=clHighlightText;
            end
           else
            begin
              canvas.Brush.Color:=clWindow;
              canvas.Font.Color :=clWindowText;
            end;
        end;
      //Hintergrund färben und Text ausgeben
      canvas.FillRect(rect);
      canvas.TextOut(rect.left+2,rect.Top+2,cells[acol,arow]);
    end;
end;

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;const Value: string);
begin
  //Zelle hat sich gändert, ganzes Grid bzw ganze Zeile neu zeichnen
  //(sender as TStringGrid).repaint;
  with sender as TStringGrid do
    begin
      rows[arow]:=rows[arow];
    end;
end;


Das Färben sollte nicht wirklich das Problem sein. Du hast es zwar nicht beschrieben, ich denke aber, das dein Problem das folgende ist:
- eine Zeile ist leer, im ondrawcell werden die Zellen farbig gemalt.
- User gibt etwas in diese Zeile ein. Für diese Zelle wird das ondrawcell aufgreufen, für alle anderen Zellen der Zeile nicht, es hat sich ja nichts geändert. Somit bleiben die restlichen Zellen grün, was du nicht willst. Oder umgedreht, der User löscht einen Zellinhalt und jetzt muß jede zwite Zelle grün gemalt werden.

du mußt bei einer Eingabe das Neuzeichnen erzwingen. Das setedittext-Ereingis kannst du z.B. verwenden. Entweder mit repaint (alles wird neu gezeichnet) oder durch Zuweisen der Zelltexte/Row-Texte, dann wird für diese Zellen auch das ondrawcellereignis ausgelöst. Prinzipiell kannst du auch invaliderect verwenden. Welche Delphiversion hast du (seh ich nicht beim schreiben ;) ). Ab der Pro liegen sie Sourcen bei. Das Gird hat ein eigenes Invaliderect, das die Zellen als Paramter hat (nicht wie das normale invaliderect die Bildschirmpos). Diese methode ist leider als private deklariert, an die kommst du nicht ran. Du kannst duir aber ein eigens Grid ableiten und diese 2 methoden (invalidaterect ruft noch eine weitere priv.methode auf) und die bei deiner kompo reinkopieren.
ein normales windows.invaliderect wird daran scheitern, das du schelcht an die erforderlichen Zellpositionen rankommst, da cellrect dir nur werte zurückgibt, wenn die Zelle sichtbar ist. (gehen tut das schon, ist aber eine ziemliche Rechnerei)

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: So 19.06.05 17:30 
Hi, Frank,

ganz herzlichen Dank für deine sehr ausführliche Antwort!

Mit Sicherheit hast du damit mein Problem gelöst. Meine Delphi-Version ist D3Prof und ich will es dann auch in D6Enter einsetzen.

Noch einen schönen Tag wünscht dir
Detlef Annies
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: So 19.06.05 19:09 
Hi, Frank,

jetzt habe ich es angepasst, und es funktioniert prächtig! :D :D :D

CU,
Detlef Annies