Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Problem in Stringgrid Customdraw


CenBells - So 10.11.02 23:37
Titel: Problem in Stringgrid Customdraw
Hallo Leute.

Ich habe ein Stringgrid und male dort fleißig herum.
Dabei tritt folgendes Problem auf. Einige der Texte sind mit einer rosa Farbe hinterlegt, obwohl das nicht so sein sollte
user defined image

Zum beispiel soll der eintrag "Tepper" nicht rosa, sondern grau hinterlegt sein. Wo ist mein Problem

Hier mein Code



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:
procedure TFrameResevierungen.vSGResevierungDrawCell(Sender: TObject; ACol,
  ARow: Integer; Rect: TRect; State: TGridDrawState);
var
  x, y: Integer;
  LText: String;
  LNoTextInCell: Boolean;
begin
  if gdFixed in State then Exit;
  with sender as TStringgrid do begin

    if ACol >= (ColCount - 2) then exit;
    LNoTextInCell := cells[ACol, ARow] = '';

    y := Rect.Top + 2;
    x := Rect.Left + 2;
    // setze erstmal den hintergrund auf weiß, zu testzwecken eingefügt
    Canvas.Brush.Color := clWhite;
    Canvas.Pen.Color := clWhite;
   
    //male jedes zweite bett grau
    if (ARow mod 4) in [0,3] then
      Canvas.Brush.Color := C_DSM_RESEVIERUNG_GREY;
    
    // male jede wochenendspalte rosa
    if DayOfWeek(EncodeDate(Fyear, FMonth, ACol)) in [1, 7] then
      Canvas.Brush.Color := C_DSM_RESEVIERUNG_WOCHENEND_COL;
    

    // hinterlege nur die 'X' gruen. Kann nur jede zweite zeile sein.
    if (ARow mod 2) = 0 then begin
      if not LNoTextInCell then begin
        // wenn text in der zelle, unterscheide ob wochenende oder nicht
        if DayOfWeek(EncodeDate(Fyear, FMonth, ACol)) in [1, 7] then
          Canvas.Brush.Color := clGreen
        else
          Canvas.Brush.Color := cllime;
        Canvas.Font.Style := Canvas.Font.Style + [fsBold];
        LText := cells[ACol, ARow];
      end
    end
    else begin
      // ansonsten beruecksichtige vorhergehende zellen, ob die zu lange   
      // namen haben. Wenn ja, dann mal den namen der vorhergehenden 
      // zelle auch in die aktuelle
      if (cells[Acol + 1, ARow] = '') or
         ((cells[ACol + 1, ARow] <> '') and (ACol <= ColCount -2)) or
         (LNoTextInCell and (cells[Acol - 1, ARow] <> '')) or
         (Canvas.TextWidth(cells[ACol - 1, ARow]) >
           (Rect.Right - Rect.Left - GridLineWidth * 2)) or
         (Canvas.TextWidth(cells[acol, ARow]) >
               (Rect.Right - Rect.Left - GridLineWidth * 2)) then begin
        if LNoTextInCell then
          x := x - ColWidths[aCol - 1] - GridlineWidth;
        if LNoTextInCell then
          LText := Cells[ACol - 1, arow]
        else
          LText := Cells[ACol, arow];
      end;
    end;
    // un jetzt schau, ob der zur zeit markierte bereich gemalt werden soll
    if (ARow >= Selection.Top) and (ARow <= Selection.Bottom) and
       (ACol >= Selection.Left) and (ACol <= Selection.Right) then
      Canvas.Brush.Color := clHighlight;
    // mal endlich...
    Canvas.FillRect( Rect );
    Canvas.TextOut(x, y, LText);
  end;
end;


Kann mir wer helfen?

Danke und Gruß
Ken


Tino - Mo 11.11.02 00:21

Hallo Ken,

ich werde aus den ganzen Farbspielen in dem Grid und dem Code nicht richtig schlau nach welchem Prinzip Du die Farben vergibst.

Gruß
TINO


CenBells - Mo 11.11.02 13:06

also,

ich vergebe die rosanen farben, wenn der tag (spalte) zu einem wochenende gehört.
Grün ist eine belegung in dem zimmer, dunkelgrün ist eine belegung am wochenende.
Grau ist zur besseren Übersichtlichkeit jedes zweite Bett.

Vielleicht kann mir nun wer helfen :D
Gruß
Ken

P.S.: Habe kommentare im Quellcode eingefügt.


Keldorn - Mo 11.11.02 20:41

Hallo

hier ist dein Fehler den du suchst:

Quelltext
1:
2:
        if LNoTextInCell then
          x := x - ColWidths[aCol - 1] - GridlineWidth;


klammere die Zeile aus und es geht

es ist immer die Zelle, links neben der rosa Spalte.
in der davon rechten Spalte setzt du die rosa farbe und schreibst den text in die Spalte links daneben

Frank

Edit: aber ich blick nich ganz durch, warum das ganze, weil du ja dann den Zellinhalt der Spalte links daneben in diese Spalte reinschreibst


CenBells - Mo 11.11.02 21:01

also das habe ich eingefügt, damit einträge in einer zelle über mehrere zellen gemalt werden, wenn die überlang sind.
also so, wie zellen verbinden bei excel oder so.

P.S.: Das macht jetzt das problem, daß der eintrag zweimal im stringgrid auftaucht...

Gruß
Ken


CenBells - Mo 11.11.02 21:28

habe es mit folgendem code gelöst.

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
          if LNoTextInCell and (Canvas.TextWidth(cells[ACol - 1, ARow]) >
              (Rect.Right - Rect.Left - GridLineWidth)) then
            x := x - ColWidths[aCol - 1] - GridlineWidth;
          if LNoTextInCell and (Canvas.TextWidth(cells[ACol - 1, ARow]) >
              (Rect.Right - Rect.Left - GridLineWidth)) then
            LText := Cells[ACol - 1, arow]
          else
            LText := Cells[ACol, arow];


Nun werden die zellen immer noch verbunden, aber die Zelle links wird nur neu gemalt, wenn dort text ist, der in diese zelle reinreicht

Gruß
Ken


Keldorn - Mo 11.11.02 22:31

hallo, verdammt, fliege ständig aus dem internet oder euer Texteditor treibt mich zur weißglut !!! :twisted:
schreib den text schon zum zweiten mal :cry: und hoffe, es war nicht umsonst

Zitat:

P.S.: Das macht jetzt das problem, daß der eintrag zweimal im stringgrid auftaucht...

stimmt, aber dein Problem war ja die Farbe :lol: 8)

habe mir nochmal diese große If-Bedingung angeschaut und den sinn nicht verstanden, soviel möglichkeiten um immer true zurückzugeben und den Text immer auch noch in die vorherige Spalte zu zeichen.

deine lösung ist aber auch nur von kurzer dauer :
- wenn du einen langen Text eingibst, oder einen langen Text kürzt, wird die Spalte rechts daneben nicht aktualisiert
füge stringgrid.repaint beim onexit ereignis ein, dann wird zumindestens wenn du z.B. tab drückst das ganze neugezeichnet.
- bring eine andere Anwendung in den vordergrund und dann wieder deine. Das stringgrid wird neugezeichnet.
Ich denke, das Canvas.brush immer die hintergrundfarbe darstellt. in einer rosa spalte ist er rosa und du zeichnest den text in die spalte links daneben (die eigentlich grau/weiß ist) da canvas.brush=rosa, ist der gesamt texthintergrund also auch rosa und nicht unbedingt das, was du willst.

in meinem jugendlichen leichtsinn ist mir jetzt folgendes eingefallen


Quelltext
1:
2:
3:
    Canvas.FillRect( Rect );
    canvas.brush.style:=bsclear; //transparent setzen
    Canvas.TextOut(x, y, LText);

damit wird jede Zelle (aller zweireihen ?!?) die über den rand geht korrekt dargestellt
nur das Fillrect müßte man noch so anpassen, daß es die gridline mit überzeichnet

Mfg Frank


CenBells - Di 12.11.02 00:44

@Keldorn
Danke

Quelltext
1:
  canvas.brush.style:=bsclear; //transparent setzen                    


diesen befehl habe ich ewigkeiten gesucht.
Nun geht es einwandfrei.

Gruß
Ken