AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Item in DrawItem ändern?

Ein Thema von Mattze · begonnen am 21. Jun 2014 · letzter Beitrag vom 23. Jun 2014
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.506 Beiträge
 
Delphi 12 Athens
 
#1

AW: Item in DrawItem ändern?

  Alt 21. Jun 2014, 21:44
Adrenalinkick, Ruh, Ehere, ein erfüllter Traum und man hat einen geilen Ausblick.

Es hat auch absolut keinen Sinn das Haus zu verschieben, nur weil es im Keller zu dunkel ist und dennoch macht das Keiner, da es "bessere" Lösungen gibt.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Mattze

Registriert seit: 6. Jan 2005
664 Beiträge
 
#2

AW: Item in DrawItem ändern?

  Alt 22. Jun 2014, 05:18
Hallo,

ICH halte die Frage nach den Grenzen eines Konzepts für durchaus berechtigt, auch wenn sie zunächst einmal dem einen oder anderen sinnfrei erscheint!

Übrigens: Eigentlich dürfte es nicht gehen, aber erstaunlicherweise scheint es doch zu funktionieren.

Delphi-Quellcode:
  
  if (index>Ftempindex) and Assigned(FOnBeforeDrawItem) then begin
    FOnBeforeDrawItem(Self, Index, Rect, State);
    FTempIndex:=index;
    exit;
  end;
im neuen DrawItem am Anfang tut es.
(FTempIndex ist eine Integer-Variable aus dem private-Bereich der neuen Listbox-Komponente und wird in Create mit -1 initialisiert.)

Es gibt noch beim ersten (und zweiten?) vertikalen Scrollvorgang ein kleines Problem, aber sonst sieht es schon gut aus und das ist verschmerzbar.

Gruß
Mattze

PS: Warum gibt es für Perlsau eigentlich nur Genie oder Anfänger?
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#3

AW: Item in DrawItem ändern?

  Alt 22. Jun 2014, 08:29
Ich finde Mattzes Ansinnen, Fragestellung, Argumenation und Vorgehensweise absolut ok. Dieses 'völlig sinnfreie Anliegen' ist ein sehr wichtiger Bestandteil einer für viele vermutlich komplett überflüssigen Tätigkeit, die unsere Gesellschaft zwar weiterbringt ('Fortschritt'), aber jedoch im eigentlichen Sinne unproduktiv und für Laien teilweise auch blödsinnig ist.

Diese offensichtlich für Einige bekloppte Tätigkeit nennt sich: Forschen und basiert in erster Linie auf Wissensdurst. Und dieser Durst nach Wissen kann nur gestillt werden, wenn Vorbehalte ("Das braucht man doch nicht", "Geht auch anders", "völlig Sinnfrei") mal außen vor gelassen werden. Diese Vorbehalte kommen in der Anwendung zum Einsatz (und sind Antrieb von so etwas wie Wirtschaftlichkeit), haben in der Forschung jedoch nichts zu suchen.

Für Einige scheint Forschung und Programmieren nichts miteinander zu tun zu haben.

Zum Thema: Endllosschleifen in ereignisgesteuerten Programmabläufen lassen sich zuverlässig über Markierungen vermeiden. Grundsätzlich geht da so:
Delphi-Quellcode:
Procedure MyEventHandler(SomeObject : TSomeObject);
Begin
  If IsHandled[SomeObject] then exit;
  IsHandled[SomeObject] := true;
  Try
    DoSomeThingWith(SomeObject); // <<< Löst das Ereignis 'MyEvent' erneut aus
  Finally
    IsHandled[SomeObject] := false;
  End
End;
Eine andere Vorgehensweise ist die, einen die Schleife auslösenden Aufruf nur dann auszuführen, wenn es unbedingt nötig ist. Ein Beispiel ist ein Grid, welches die Spaltenbreite automatisch anpasst, wenn der darzustellende Text breiter als die augenblickliche Spaltenbreite ist. Dann wird die Breite ja nur gesetzt, wenn die Spalte noch nicht breit genug war. Hier findet zwar ein rekursiver Aufruf statt, aber nach dem ersten Aufruf ist Schluss, da die Breite ja beim 2. Aufruf passt.
Delphi-Quellcode:
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  sg : TStringGrid;
begin
  if not (Sender is TStringGrid) then exit;
  sg := TStringGrid(Sender);
  w := sg.Canvas.TextWidth(sg.Cells[aCol, aRow]);

  if w>sg.ColWidths[aCol] then
    sg.ColWidths[aCol] := w; // <<< löst ein erneuten Aufruf von DrawCell aus!
  ...
end;
Hier würde ich vermutlich den zweiten Ansatz nehmen, denn der Text muss ja nur verändert werden, wenn noch nicht geändert wurde.

Eigentlich ist das 2.Pattern eine Spezialisierung des 1.Patterns, denn das [Delphi]IsModified[SomeObject][/delpi] wird ja durch die Änderung des Objekts abgebildet.

Geändert von Dejan Vu (22. Jun 2014 um 08:43 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.506 Beiträge
 
Delphi 12 Athens
 
#4

AW: Item in DrawItem ändern?

  Alt 22. Jun 2014, 09:19
Ich finde Mattzes Ansinnen, Fragestellung, Argumenation und Vorgehensweise absolut ok.
OnDraw ist zum Malen da und hat nichts an den Daten zu ändern.

Und ja, ich kenn einige Komponenten, welche jedesmal im OnDraw irgendwelche Daten überschreiben, oder erst dort Operationen ausführen, welche eigentlich in ein OnChange reingehören würden.
Das Verhalten solcher Komponenten ist völlig undurchschaubar, da gedade das Paintereignis an unbestimmter Stelle ausgeführt wird und wozu soll ein einmaliges Ereignis bei jeder Zeichenoperation ausgeführt werden?

Vorallem der Code in #16 ist ein gutes Beispiel.
Jenachdem wie oft das Ding gezeichnet werden muß, steht jedesmal was Anderes drin.


Und ja, wenn man was am Ausgabeformat oder den Daten ändert, dann muß sich das Ding doch neu zeichnen.
Drum macht man sowas auch nicht in einer Zeichenoperation.

Wenn man vollkommene Freiheit haben will, dann nimmt man eben sowas wie das VirtualTreeView oder (falls die Komponente es kann) versetzt die komponente in einen virtuellen Modus,
wo man im OnPaint alles anzeigen kann, was man will.
Aber auch da gilt, daß man z.B. an der Item-Größe nicht erst im OnPaint rumzuspielen hat.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Mattze

Registriert seit: 6. Jan 2005
664 Beiträge
 
#5

AW: Item in DrawItem ändern?

  Alt 22. Jun 2014, 09:42
Hallo himitsu,

und damit sind wir genau da, woher meine Frage überhaupt kam - Virtualtreeview.
Ich habe mich gefragt, warum der das kann und z. Bsp. die Listbox nicht.
Beantworten kann ich diese Frage nicht richtig, aber für die Listbox habe ich es halt "irgendwie" auch hinbekommen.
Wie gesagt, ich hätte gedacht, dass das überhaupt nicht möglich ist, schon theoretisch nicht!

Aber nach Deinem Hinweis habe ich gemerkt, dass das ganz und gar nicht sauber ist und das unselige OnBeforeItemDraw wieder entfernt.
Fragt sich eben nur, warum das dann manche Komponenten überhaupt zulassen?

Gruß
Mattze
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.506 Beiträge
 
Delphi 12 Athens
 
#6

AW: Item in DrawItem ändern?

  Alt 22. Jun 2014, 10:06
Nja, diese Komponenten sind halt extra darauf ausgelegt, daß dort die Anzeige nicht aus enthaltenen Daten kommt.

Aber auch dort bleibt das Grundsätzliche Verhalten bestehen.
- entweder die Daten werden vor/beim Einfügen bereits angepasst
- oder es wird bei der Anzeige nur die Zeichenoperation geändert, aber so Sachen wie die Größe sollten dabei unangetastet bleiben.

Stell dir mal vor du fängt auf einem A4-Blatt an mit Malen und mittendrin kommst du auf die Idee "ach was, ich nehm jetzt doch A3".
Bzw. jedes Mal, wenn sich jemand dein Bild anguckt, tauschst du das Papier dahinter ... morgen vielleicht mal A8.

Fragt sich eben nur, warum das dann manche Komponenten überhaupt zulassen?
Man denkt nicht daran, daß jemand auf diese Idee kommen könnte und baut somit keinen Code ein, welcher das abfängt.

Wenn es nicht geht, dann wird derjenige es schon mitbekommen, wenn es dann irgendwo kanllt.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (22. Jun 2014 um 10:11 Uhr)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#7

AW: Item in DrawItem ändern?

  Alt 22. Jun 2014, 23:31
Stell dir mal vor du fängt auf einem A4-Blatt an mit Malen und mittendrin kommst du auf die Idee "ach was, ich nehm jetzt doch A3".
Bzw. jedes Mal, wenn sich jemand dein Bild anguckt, tauschst du das Papier dahinter ... morgen vielleicht mal A8.
Bis es dann passt. Und wenn es nicht passt, wird es passend gemacht. Das kann man vorher machen (und man sollte es ja in diesem konkreten Beispiel auch), aber wenn man es im OnPaint machen will, wieso nicht? Man lädt Daten ja auch im Getter (lazy load) wieso keine dynamische Anpassung im paint? Bloß weil man 'es nicht macht'? Es geht, ist einfach, direkt und sicher (wenn man weiß, was man macht).
  Mit Zitat antworten Zitat
Antwort Antwort


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 07:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz