Einzelnen Beitrag anzeigen

Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.538 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Listbox ohne DrawItem-Event

  Alt 3. Dez 2013, 20:50
Was der schöne Günther hier als Beispiel gezeigt hat, ist eine von mehreren Möglichkeiten.

Man kann den einzelnen ListItems, wenn man sie bereits zur Desingzeit anlegt, die gewünschten Einstellungen für Font-Farbe und Textattribute über den Object-Inspector zuweisen. Dabei muss man unter StyledSettings z.B. das "ssFontColor" deaktivieren, wenn man dem ListItem unterschiedliche Farben zuweisen möchte.

Eine weitere Möglichkeit wäre, das alles zur Laufzeit machen, wenn die Listbox mit den ListItems erstellt wird.

In beiden Fällen möchte man aber vielleicht zur Laufzeit die Farben von den Inhalten der Listbox unterschiedlich gestalten.

Um z.B. die Textfarbe rot zu machen, wenn der Text des Elements "ListBoxItem2" lautet, könnte man das in dem ApplyStyleLookup-Event so machen:

Code:
procedure TForm22.ListBoxItem7ApplyStyleLookup(Sender: TObject);
begin
  With TListBoxItem(sender) do begin
    StyledSettings := StyledSettings - [TStyledSetting.ssFontColor];

    if Text = 'ListBoxItem2' then
      FontColor := TAlphaColorRec.red
    else
      FontColor := TAlphaColorRec.black;
  end;
end;
Hierzu ist natürlich erforderlich, dass dem einzelnen ListBoxItem entweder über den Object-Inspector zur Designzeit unter "OnApplyStyleLookup" die ApplyStyleLookup-Procedure zugewiesen wurde, oder aber zur Laufzeit, wenn die ListItems erstellt worden sind.

Aber weil Du speziell die OnDrawItem-Events angesprochen hast: Die gibt es in der Tat nicht mehr so für die Listbox, wie wir sie von der VCL kennen.

Es existiert aber ein OnPaint bzw. OnPainting-Event für das ListBoxItem.

Hier kann man, ganz wie in alter VCL-Manier zeichnen, wie man möchte. Das ist z.B. nützlich, wenn man viel Daten in Objekten gespeichert hat, die man mit den ListBoxItems verbunden hat (oder sonst irgendwo in einer Liste oder Datenbank hält). Für das untenstehende Demo habe ich es aber einfach gehalten und demonstriere es ohne verbundene Datenobjekte. Die ListboxItems enthalten keinen Text (sollten sie auch nicht, da der sonst per Default gezeichnet wird), einen Text hole ich daher aus dem Namen der ListboxItems. Es soll ja auch nur der Zeichenvorgang demonstriert werden:

Code:
procedure TForm22.ListBoxItem1Painting(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
var
  Flags: TFillTextFlags;
  save :TCanvasSaveState;
begin
  With TListBoxItem(sender) do begin
    canvas.BeginScene;

    canvas.Fill.Kind := TBrushKind.bkSolid;

    Flags := [TFillTextFlag.ftRightToLeft];

    if Name = 'ListBoxItem3' then begin
      if ListBox1.ListItems[ListBox1.ItemIndex] <> TListBoxItem(sender) then begin
        Save := canvas.SaveState;
        canvas.IntersectClipRect(ARect);
        Canvas.Clearrect (Arect, TAlphaColorRec.Yellow);
        canvas.RestoreState(save);
      end;
    end;

    if Name = 'ListBoxItem2' then
      Canvas.Fill.Color := TAlphaColorRec.red
    else
      Canvas.Fill.Color := TAlphaColorRec.black;

    Canvas.FillText(ARect, name, true, 1, flags, TTextAlign.taTrailing, TTextAlign.taCenter);

    canvas.EndScene;
  end;

end;
Hinweis: Um den Hintergrund hier auch unter Delphi XE5 (und XE4) farblich anders anzeigen zu können (wenn der Text "ListboxItem3" lautet), verwende ich einen kleinen Workaround. Denn Clearrect zeichnet den ganzen Hintergrund der Listbox gelb, nicht nur wie gewünscht, den Rect-Bereich des ListboxItems. Mit "canvas.IntersectClipRect(ARect)" beschränke ich das Zeichnen auf den gewünschten Clipping-Bereich.

Anwender von Delphi XE3 können sich das Speichern des Canvas-Status und erzeugen des Clippings-Bereichs, bzw. restaurieren sparen, da funktioniert noch alles so, wie es soll.

Ich habe hier mal einen Screenshot der obigen Quelltexte zur Laufzeit angehängt (und auch mal das Projekt selber).
Miniaturansicht angehängter Grafiken
listboxitems.jpg  
Angehängte Dateien
Dateityp: zip projektdemo.zip (99,8 KB, 24x aufgerufen)

Geändert von Harry Stahl ( 3. Dez 2013 um 22:38 Uhr) Grund: Grafik-Anlage vergessen
  Mit Zitat antworten Zitat