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/)
-   -   Listbox ohne DrawItem-Event (https://www.delphipraxis.net/177806-listbox-ohne-drawitem-event.html)

Flottenmanagement 28. Nov 2013 11:01

Listbox ohne DrawItem-Event
 
Hallo zusammen!

fehlt standardmäßig unter Embarcadero RAD Studio XE5 die Events DrawCell fürs StringGrid, DrawItems für eine Listbox? Wir brauchen die Events, zum Beispiel um einzelne Einträge farbig zu markieren. Leider finden wir die Events nichtim Objektinspektor. Gibt es dort equivalente Events die geeignet sind?

LG

Flottenmanagement:wink:

Der schöne Günther 28. Nov 2013 12:12

AW: Listbox ohne DrawItem-Event
 
Hallo -

Ich kenne mich mit FireMonkey zwar kein Stück aus, aber das Event scheint es (zum Glück) wohl wirklich nicht mehr zu geben. Stattdessen scheint man (wesentlich intuitiver) auf den entsprechenden TListBoxItems die Dinge einstellen zu können.

Eine Hintergrundfarbe finde ich auf Anhieb nicht (kenne FireMonkey noch nicht), aber die Schriftfarbe bekomme ich beispielsweise so umgestellt:

Delphi-Quellcode:
var
   myListBoxItem: TListBoxItem;
begin

   myListBoxItem := ListBox1.ListItems[1];

   myListBoxItem.StyledSettings := ListBoxItem2.StyledSettings - [TStyledSetting.ssFontColor];
   myListBoxItem.TextSettings.FontColor := TAlphaColorRec.Red;

Flottenmanagement 29. Nov 2013 07:04

AW: Listbox ohne DrawItem-Event
 
Vielen Dank für die Hilfe!
wir probieren es direkt aus:-D

Harry Stahl 3. Dez 2013 19:50

AW: Listbox ohne DrawItem-Event
 
Liste der Anhänge anzeigen (Anzahl: 2)
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).


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