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/)
-   -   Delphi Stringgrid spät anzeigen bzw. füllen (https://www.delphipraxis.net/35784-stringgrid-spaet-anzeigen-bzw-fuellen.html)

Hansa 11. Dez 2004 19:58


Stringgrid spät anzeigen bzw. füllen
 
Hi,

das Problem ist jetzt nicht gewaltig, aber einer weiß bestimmt was. Ich lasse Daten aus DB in einem Stringgrid anzeigen. Das geht auch, aber es dauert. Hierfür ist nicht die Datenbank vorantwortlich, sondern Delphi bzw. eher Windows. Das ganze liegt an der grafischen Darstellung. Setze ich visible des Stringgrids auf false und erst wenn die Daten da sind auf true, so geht es viel schneller.

Jetzt ist die Sache nur so, daß ich in anderen Fällen das Stringgrid leer anzeige mit FixedRows usw. so daß man schon mal grob sieht was später kommt, selbst wenn nicht alles erforderliche eingegeben wurde. Ich will also das ständige Aktualisieren unterdrücken.

omata 12. Dez 2004 17:25

Re: Stringgrid spät anzeigen bzw. füllen
 
Moin,

hast du ein eigenes OnDrawCell-Ereignis? Wenn ja, dann häng doch dieses Ereignis solange ab, wie du deine Daten einliest.

OnDrawCell:=nil;

Oder was machst du da genau?

MfG
Thorsten

Hansa 12. Dez 2004 18:01

Re: Stringgrid spät anzeigen bzw. füllen
 
Stimmt, auf Nil setzen. Nur wo ? Bzw. wo setze ich a, bestn meine eigene Prozedur wieder ?

omata 12. Dez 2004 20:35

Re: Stringgrid spät anzeigen bzw. füllen
 
Moin,

naja am Anfang der Einleseroutine auf NIL setzten und am Ende wieder auf die Prozedur.


MfG
Thorsten

Sharky 13. Dez 2004 07:11

Re: Stringgrid spät anzeigen bzw. füllen
 
Hai Hansa,

hast Du es schon einmal mit BeginUpdate / EndUpdate versucht? Das sollte man beim einfügen von großen Datenmengen immer verwenden.

Delphi-Quellcode:
procedure SGBeginUpdate (sg : TStringGrid);
var
  ndx : Integer;
begin
  for ndx := 0 to sg.RowCount-1 do
  begin
    sg.Rows[ndx].BeginUpdate;
  end;
  for ndx := 0 to sg.ColCount -1 do
  begin
    sg.Cols[ndx].BeginUpdate;
  end;
end;

procedure SGEndUpdate (sg : TStringGrid);
var
  ndx : Integer;
begin
  for ndx := 0 to sg.RowCount-1 do
  begin
    sg.Rows[ndx].EndUpdate;
  end;
  for ndx := 0 to sg.ColCount -1 do
  begin
    sg.Cols[ndx].EndUpdate;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   SGBeginUpdate(StringGrid1);
   // Füllen des StringGrids mit Daten
   SGEndUpdate(StringGrid1);
end;

Hansa 13. Dez 2004 12:57

Re: Stringgrid spät anzeigen bzw. füllen
 
Hi,

ich bin jetzt dran mit dem Prozedur auf nil setzen usw. Das ganze müßte im BtnClick passieren. Da passen aber die erwarteten Parameter überhaupt nicht zusammen. Hat jemand ein Beispiel dafür ? Und natürlich auch wieder zurück auf die Prozedur setzen. Weiß nicht mehr wie das geht. :mrgreen: Bzw. wo steht das im Handbuch / OH ?

omata 13. Dez 2004 18:40

Re: Stringgrid spät anzeigen bzw. füllen
 
Moin,

was spricht gegen BeginUpdate und EndUpdate? (toller Einwand - danke)

Nun das Abhängen geht folgendermaßen:

Delphi-Quellcode:
StringGrid.OnDrawCell:=nil;
...
StringGrid.OnDrawCell:=StringGridDrawCell;
MfG
Thorsten

Hansa 13. Dez 2004 18:45

Re: Stringgrid spät anzeigen bzw. füllen
 
Zitat:

Zitat von omata
was spricht gegen BeginUpdate und EndUpdate? (toller Einwand - danke)

Nichts, nur daß es nicht um Update usw. geht.

Hierdrum gehts :

Zitat:

Zitat von Hansa
Ich lasse Daten aus DB in einem Stringgrid anzeigen. Das geht auch, aber es dauert. Hierfür ist nicht die Datenbank vorantwortlich, sondern Delphi bzw. eher Windows. Das ganze liegt an der grafischen Darstellung. Setze ich visible des Stringgrids auf false und erst wenn die Daten da sind auf true, so geht es viel schneller.


mschaefer 13. Dez 2004 21:08

Re: Stringgrid spät anzeigen bzw. füllen
 
N´abend Hansa,

denke ich ahne worum es geht. Eigentlich gehöre ich schon längst in die Schlafphase...
Also, das aktualisieren bei einem Datensatzwechsel dauert wohl zu lange. Hoffe ich liege da richtig.

Wenn das Dein Problem ist, dann lasse das StringGrid zunächst mit visible auf false.
Du nimmst einen Timer. Der Timer wird bei jedem OnChage-Ereignis der DataSource auf enablde
geschaltet und das StringGrid auf visible = false. Im Timerereignis schaltest Du den Timer
wieder auf Disabled und das StringGrid visible auf true.

Dadurch wird Dein StringGrid bei einem Onchage Ereignis nicht angezeigt, besser Deine Füllroutine noch nicht aufgerufen. Bei selektiertem Datensatz schlägt dann mit kleiner Verzögerung das Timerereignis
zu und führt nun Deine Füllroutine aus und setzt das Grid auf visible.

Gute Nacht // Martin

Hansa 13. Dez 2004 21:16

Re: Stringgrid spät anzeigen bzw. füllen
 
Zitat:

Zitat von mschaefer
...denke ich ahne worum es geht. Eigentlich gehöre ich schon längst in die Schlafphase...
Also, das aktualisieren bei einem Datensatzwechsel dauert wohl zu lange. Hoffe ich liege da richtig.
...

Die Klarstellung steht 2? Beiträge oben drüber. :lol: Und ganz am Anfang steht auch noch was. Und mit dem Procedure auf nil setzen, da warte ich nur auf Infos. Bisher kommt eben nichts. :mrgreen:

omata 13. Dez 2004 22:42

Re: Stringgrid spät anzeigen bzw. füllen
 
Moin Hansa,

habe dir doch ein Beispiel geliefert, da bist du leider nicht drauf eingegangen

schade

MfG
Thorsten

mschaefer 14. Dez 2004 07:29

Re: Stringgrid spät anzeigen bzw. füllen
 
Moin, moin,

also Hansa Du bist auf dem Holzweg - Eiche :mrgreen:

Mit einfach mal was auf Nil setzten ist das nicht getan. Du kannst Dir ein Grid ableiten und das OnPaint Ereignis solange blockieren, wie der Update läuft. Also letzlich die Routine in einer If Abfrage solange nicht ausführen solange Dein Ipdate läuft und am Ende rufst Du Paint nochmal auf. Ohne Komponentenableitung geht es meines Wissens nach nicht den Flaschenhals Windows Bildakutalisierung zu umgehen.

Ansonsten höre auf dne Hai, den Sharky hat den anderen Flaschenhals, die fürchterlich langsamen Stringlisten ins Echolot genommen indem er Dir Begin- und Endupdate Routinen
zugeschwemmt hat.

Möge der Tag Kekse gute Laune und viele Lösungen bringen // Martin

Sharky 14. Dez 2004 08:06

Re: Stringgrid spät anzeigen bzw. füllen
 
Zitat:

Zitat von Hansa
...Nichts, nur daß es nicht um Update usw. geht. ...

Das ist schon klar.
BeginUpdate macht aber nichts anderes als dafür zu sorgen das, in diesem Fall das SG, nicht neugezeichnet wird bis das EndUpdate aufgerufen wird. Genau dies ist nämlich das Nadelöhr beim Füllen von TStringListen, TListViews usw.

Aber Du kannst ja beide genannten Möglichkeiten kombinieren:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  myDrawCell : TDrawCellEvent;
begin
  myDrawCell := StringGrid1.OnDrawCell; // Event "merken"
  StringGrid1.OnDrawCell := nil; // Kein OnDrawCell
  SGBeginUpdate(StringGrid1);

  // Füllen des StringGrids mit Daten

  SGEndUpdate(StringGrid1);
  StringGrid1.OnDrawCell := myDrawCell; // gemerketes Event zuweisen
end;

Hansa 14. Dez 2004 08:54

Re: Stringgrid spät anzeigen bzw. füllen
 
Kurze Zwischenfrage : setze ich OnDrawCell auf nil, so tut sich absolut nichts. Ich kann es genau so gut weglassen. :shock:

Sharky 14. Dez 2004 08:56

Re: Stringgrid spät anzeigen bzw. füllen
 
Zitat:

Zitat von Hansa
Kurze Zwischenfrage : setze ich OnDrawCell auf nil, so tut sich absolut nichts. Ich kann es genau so gut weglassen. :shock:

Eigentlich auch richtig :oops:
Durch das BeginUpDate wird ja das neu zeichnen unterbunden. Darum sollte das OnDraw beim füllen eh nicht aufgerufen wird.

Sharky 14. Dez 2004 09:10

Re: Stringgrid spät anzeigen bzw. füllen
 
Ich habe eben mal etwas gespielt: Ein StringGrid mit 5 Spalten und 10.000 Zeilen.
Ohne BeginUpdate / EndUpdate dauert das füllen jeder Zelle mit einem festen String ca. 140 ms. Mit BeginUpdate nur noch ca. 50ms.
Ob ich das OnDrawCell "deaktiviere" macht keinen Unterschied wenn BeginUpDate verwendet wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:34 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