AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Fontfarbe in TStringgrid ändern ;-)

Ein Thema von Roadrunner.1 · begonnen am 3. Mai 2017 · letzter Beitrag vom 5. Mai 2017
Antwort Antwort
Seite 1 von 2  1 2   
Roadrunner.1

Registriert seit: 3. Mai 2009
20 Beiträge
 
Delphi 10.3 Rio
 
#1

Fontfarbe in TStringgrid ändern ;-)

  Alt 3. Mai 2017, 10:25
Hi Zusammen,

ja, ja, ja, die Frage wurde schon 1000 mal gestellt und ich soll die Suche verwenden. Also nach einer Stunde bekomme ich MEIN Problem
nicht gelöst. Vielleicht liegt es aber auch Delphi XE5 und jemand hat eine Idee.

Also was will ich?
Bestimmte Einträge in einem Stringgrid in einer anderen Fontfarbe darstellen. Standartantwort wäre z.B.:

procedure TForm.SGDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
begin
if (ACol=4) and (ARow>0) then begin
with SG.Canvas do begin
Font.Color:=clred;
FillRect(Rect);
Textout(Rect.Left+2,Rect.Top+2, SG.Cells[ACol,ARow]);
end;
end;
end;

Merkwürdig daran ist, das auch alle anderen Zellen gemalt werden. Wie's mir scheint wird hier ÜBERMAHLT nicht "statt dessen" gemalt, oder?

OK. Nun zu meinem Problem: Hat eine übermalte Zelle den Fokus (sieht dann anders aus, aber für meine Zwecke OK) und gehe ich dann mit TAB
aufs nächste Steuerelement, so wird der Eintrag nicht rot sondern schwarz dargestellt! Selbst ein Repaint, Invalid oder die Zuweisung eines neuen
Textes in der onExit des Stringgrids führt zu keiner Besserung. Folgendes führt zu einer Standartfarben (schwarz) Ausgabe:

procedure TForm.SGExit(Sender: TObject);
begin
with SG do begin
Cells[4,4]:='Test';
end;
end;

Das "Test" erscheint also in schwarz statt in rot wenn beim Fokuswechsel diese Zelle markiert war. War hingegen eine andere markiert wird
"Test" in rot dargestellt!

Meine letzte Idee war DrawCell in onExit aufzurufen, aber wo bekom' ich mein Rect Parameter her, und wieso ist das alles so aufwendig?
Des Weiteren hab' ich Breakpoints gesetzt, und DrawCell wird nach der Zuweisung in OnExit schon mit ACol=4 und ARow=4 aufgerufen, aber
dieser Eintrag nicht rot dargestellt.

Hat irgend einer eine Idee?
Christian Drenkard
--
mfg.
Christian Drenkard
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.330 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 3. Mai 2017, 10:58
Auch wenn ich noch nicht ganz schlau aus deiner Beschreibung werden:
Schmeiß das verdammte "WITH" aus deinem Source. Es kann durchaus sein, dass damit dein Problem schon behoben ist.
Peter
  Mit Zitat antworten Zitat
Roadrunner.1

Registriert seit: 3. Mai 2009
20 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 3. Mai 2017, 11:34
Hallo Peter,

danke fürs lesen. Aber am With liegt's mit hoher Wahrscheinlichkeit nicht, weil das ja nichts mit dem Fokus (Programmablauf) zu tun hat.

Hier vielleicht nochmal kurz was das Problem ist:

Ist eine Zelle in einem Stringgrid über onDrawCell "gemahlt" und hat den Fokus, und wird dann via Tastatur mittels der
Taste "Tab" aufs nächste Steuerelement gewechselt, wird die eigenen onDrawCell nicht nochmal aufgerufen (obwohl sich das
Aussehen ändert). Auch ein erneutes Zuweisen des Inhaltes, und damit das Aufrufen von onDrawCell in der onExit, führt nicht
zum gewünschten Ergebnis, weil wohl nach onExit da nochmal drüber gemahlt wird.

Den Effekt hab' ich auch wenn ich mit der Maus ein anderes Steuerelement wähle.

Was ich bräuchte wäre ein "Wenn Stringgrid Fokus verliert, onDrawCell der Fokusverlierenden Zelle aufrufen". Wie geschrieben
geht das in onExit des Stringgrids wohl leider nicht.
Christian Drenkard
--
mfg.
Christian Drenkard
  Mit Zitat antworten Zitat
Roadrunner.1

Registriert seit: 3. Mai 2009
20 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 3. Mai 2017, 12:12
Hier mal ein komplettes Programm. Formular, Stringgrid, Button

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Grids;

type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
begin
if (ACol=4) and (ARow>0) then begin
with StringGrid1.Canvas do begin
Font.Color:=clred;
FillRect(Rect);
Textout(Rect.Left+2,Rect.Top+2, StringGrid1.Cells[ACol,ARow]);
end;
end;
end;
end.
(Options von TStringgrid zusätzlich zum Default: goEditing, goAlwaysShowEditor)

Nach meinem Verständnis sollte folgendes Bild nicht möglich sein einzugeben (Die 12345 müsste rot sein) Siehe Anhang:
Hierzu einfach Spalte 4 gefüllt, Spalte 5 gefüllt dann einen anderen Wert von Spalte 5 ausgewählt und TAB gedrückt.

Sie steht auch weiter links und höher, vermutlich funkt der InplaceEditor dazwischen, aber wie und wann schalte ich den ab,
damit der nicht nach mir nochmal drüber malt? In onExit hatte ich jetzt schon versuchsweise das goEditing und goAlwaysShowEditor
abgeschaltet, aber hübsch ist anders (Blauer Hintergrund bleibt, fette Schriftart und falsche Ausrichtung).

Oder sollte ich versuchen dort die Schriftart zu Ändern? Geht das überhaupt?
Miniaturansicht angehängter Grafiken
capture.jpg  
Christian Drenkard
--
mfg.
Christian Drenkard
  Mit Zitat antworten Zitat
Roadrunner.1

Registriert seit: 3. Mai 2009
20 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 3. Mai 2017, 15:39
OK, falls es noch interessiert, oder falls jemand eine bessere Lösung hat, hier wie ich es jetzt gelöst habe.

Im onExit versetz ich den Fokus um eine Zelle nach links.
Im onEnter setzt ich den Fokus auf 0,Row.
Im CanSelectCell wird dann der Fokus auf die Eingabespalte versetzt (macht die sowieso schon, damit der User nur die Zeile klicken braucht).

Damit onExit auf eine nicht erlaubte Spalte setzen kann, Variable die sich merkt ob gerade onExit läuft.
Um Spalte und Zeile gleichzeitig setzen zu können eine ReEnter Sperre für CanSelectCell.

Von Nachteil ist jetzt vor allem, das wenn der User den Fokus auf den Stringgrid ändert, dass dann
die bis dahin rote Zahl wieder schwarz wird... Wäre wohl zu lösen wenn der gesammte Text der Zelle als
markiert dargestellt werden würde, aber hier half bisher nicht mal ein SelectAll für den InplaceEditor.
Christian Drenkard
--
mfg.
Christian Drenkard
  Mit Zitat antworten Zitat
Benutzerbild von scrat1979
scrat1979

Registriert seit: 12. Jan 2007
Ort: Sulzbach a.d. Murr
1.026 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 3. Mai 2017, 23:10
Schau dir mal von Bergsoff Das NextGrid an. Ist einfach der Hammer und beherrscht das was du möchtest... Der Umstieg lohnt sich in jedem Fall und die Bedienung ist super simple!
Michael Kübler
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.330 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 4. Mai 2017, 07:50
Gestern hatte ich leider keine Zeit mehr, um mir das Problem nochmal genauer anzusehen.

Soweit ich mich erinnern kann, musst du dich immer um das Zeichnen jeder Zelle kümmern. Also nicht nur bei denen, die du anders darstellen willst.
Ich kann es hier im Moment nicht testen (gerade kein Delphi verfügbar), aber wenn du den Source in etwa so änderst, sollte es besser funktionieren:
Delphi-Quellcode:
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
 State: TGridDrawState);
var
  grdCanv : TCanvas; // Dadurch kürze Schreibweise ohne das "WITH"
  OldColor : TColor;
begin
  grdCanv := StringGrid1.Canvas;
  OldColor := grdCanv.Font.Color;
  if (ACol=4) and (ARow>0) then begin
    grdCanv.Font.Color:=clred;
  end;
  grdCanv.FillRect(Rect);
  grdCanv.Textout(Rect.Left+2,Rect.Top+2, StringGrid1.Cells[ACol,ARow]);
  // Statt Textout ist vielleicht TextRect die bessere Wahl
  grdCanv.Font.Color := OldColor;
end;
Auch wenn das "with" hier nicht das Problem ist, solltest du es vermeiden. Es verursacht immer wieder mal Probleme.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.934 Beiträge
 
Delphi 12 Athens
 
#8

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 4. Mai 2017, 08:30
Soweit ich mich erinnern kann, musst du dich immer um das Zeichnen jeder Zelle kümmern. Also nicht nur bei denen, die du anders darstellen willst.
Um das etwas zu präzisieren: Das wird über das Property DefaultDrawing gesteuert. Ist das true, malt das StringGrid vor dem Event schon mal den Text in die Zelle. Das ist der Übermalen-Effekt, den du schon bemerkt hast. Wenn DefaultDrawing auf False steht, musst du aber eben auch alle Zellen selbst malen. Dabei solltest du allerdings den Inhalt des State-Parameters berücksichtigen.

Weiterhin gibt es zu bedenken, daß ein aktiver Editor in einer Zelle selbst das Malen übernimmt. Da du goAlwaysShowEditor aktiv hast, bleibt der InplaceEditor sichtbar (und auch für die Textdarstellung zuständig) wenn du das Grid verlässt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
664 Beiträge
 
Delphi 12 Athens
 
#9

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 4. Mai 2017, 09:19
Wie Uwe schon gesagt hat, malt der Inplace-Editor den Text neu, wenn das Grid den Focus verliert. Dabei kannst du die Textfarbe nicht beeinflussen. Das OnDrawCell des Grid ist hier nicht mehr zuständig.

Im OnExit den Text neu zu malen ist auch keine Option, denn das kommt zu früh. Der Inplace-Editor malt später nochmal drüber.

Man muss also eine Möglichkeit finden, den Text verzögert zu malen, nachdem der Inplace-Editor fertig ist.

Deshalb meine Lösung mit einem Timer:

Nimm einem Timer, setze Enabled auf false und Interval auf 10.

Im OnExit des Grid setzt du nur Timer.enabled:=true; Der Timer-Event sieht dann so aus:
Delphi-Quellcode:
procedure TForm1.TimerTimer(Sender: TObject);
var Rect: TRect;
begin
  if (StringGrid1.Col=4) and (StringGrid1.Row>0) then begin
    Rect:=StringGrid1.CellRect(StringGrid1.Col, StringGrid1.Row);
    StringGrid1.Canvas.Font.Color:=clred;
    StringGrid1.Canvas.FillRect(Rect);
    StringGrid1.Canvas.Textout(Rect.Left+2,Rect.Top+2, StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row]);
    Timer.Enabled:=false;
  end;
end;
Nicht besonders schön, funktioniert aber.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.934 Beiträge
 
Delphi 12 Athens
 
#10

AW: Fontfarbe in TStringgrid ändern ;-)

  Alt 4. Mai 2017, 09:22
Man muss also eine Möglichkeit finden, den Text verzögert zu malen, nachdem der Inplace-Editor fertig ist.
... oder man nimmt das goAlwaysShowEditor weg.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:14 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