Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Farbige Listbox (https://www.delphipraxis.net/105757-farbige-listbox.html)

XXcD 29. Dez 2007 02:20


Farbige Listbox
 
Hallo,
ich müsste in einer Listbox einzelne Items farbig machen.
Mein Problem ist ich muss das in die OnShow Routine reinkriegen.
Soweit ich weiß geht das ja nur in DrawItem.

Kann mir da einer helfen oder hat einer eine bessere Idee mit einer anderen Komponente?

ManfredG 29. Dez 2007 06:09

Re: Farbige Listbox
 
Hallo,
verwende doch statt der TListbox ein TListView.
Dort hast du das Ereignis OnCustomDrawItem. Dort läßt sich die Hintergrundfarbe der Zeile einfach einstellen, ohne daß du dich um den ganzen Inhalt kümmern mußt.
Beispiel:

Delphi-Quellcode:
procedure THF.FilesCustomDrawItem(Sender: TCustomListView; Item: TListItem;
  State: TCustomDrawState; var DefaultDraw: Boolean);
var Attrs: Integer;
    pSi: PShellItem;
    nCol: boolean;
begin
  nCol:=TRUE;
  if (Length(StC1.Caption)>0)and(StC1.Tag>0) then begin // irgend eine Bedingung...
    if pos(uppercase(StC1.Caption),uppercase(pSi.DispName))>0 then begin
      Files.Canvas.Brush.Color:=StC1.Tag; // Farbe setzen woher sie auch immer kommt
      nCol:=FALSE; // Kennezeichen für Farbe ist gesetzt
    end;
  end;
  if (Length(StC2.Caption)>0)and(StC2.Tag>0) then begin // gleichartig für eine andere Farbe
    if pos(uppercase(StC2.Caption),uppercase(pSi.DispName))>0 then begin
      Files.Canvas.Brush.Color:=StC2.Tag;
      nCol:=FALSE;
    end;
  end;
  // wenn keine Bedingung für eine der beiden Farben, dann Fensterfarbe setzen
  if NCol then Files.Canvas.Brush.Color:=clWindow;
end;
Den Rest erledigt das TListView selbst, wenn DefaultDraw=TRUE
(StC1 und StC2 sind TStaticText in deren Tag eine Farbe steht und dessen Text mit dem Inhalt der Zeile verglichen wird)
TListView auf ViewStyle=vsReport setzen und die Breite der Spalte anpassen.

Gruß Manfred

Hansa 29. Dez 2007 06:31

Re: Farbige Listbox
 
Eine Listview verwenden, um die Sachen wesentlich komplizierter zu machen, die die Listbox schon hat, oder wie ? :shock:

Delphi-Quellcode:
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  if Index mod 2 = 0 then begin
    Listbox1.Canvas.Brush.Color := clRed;
    Listbox1.Canvas.FillRect(Rect);
    Listbox1.Canvas.TextOut(Rect.Left, Rect.Top, Listbox1.Items[Index]);
  end
  else
    Listbox1.Canvas.TextOut(Rect.Left, Rect.Top, Listbox1.Items[Index]);
end;
Das färbt jede zweite Zeile rot. Du kannst aber genausogut die letzten Lottozahlen verwenden, um genau die Zeilen mit den entsprechenden Nummern zu färben. :lol: Den Inhalt der Zeilen kann man auch für sowas verwenden.

P.S.: der Style der Listbox muss im OI auf OwnerDraw??? gesetzt werden !

ManfredG 29. Dez 2007 09:21

Re: Farbige Listbox
 
Hallo Hansa,
a) OwnerDraw muß gesetzt werden
b) was ist an einem ListView kompliziert
und
c) schau dir mal die Rahmen an, wenn du die Zeilen selektierst, wenn du von einer Zeile auf die nächste klickst (einmal auf den Text und einmal auf eine leere Position rechts neben den Text)
d) wenn schon, dann "Listbox1.Canvas.TextOut(Rect.Left+1, Rect.Top+1, Listbox1.Items[Index])"
:roll:
Gruß Manfred

XXcD 29. Dez 2007 10:58

Re: Farbige Listbox
 
Das Problem ist ich müsste das in das OnShow ereignis reinkriegen.
Ich möchte damit anzeigen wer online oder offline ist.

Hier mal der Code:
Delphi-Quellcode:
Listbox3.Clear;
if assigned(FResult) then begin
    if FMysql.Status<>MYSQL_STATUS_READY then
      ShowMessage('Ein Ergebnis wurde unvollständig gelesen!');
      FreeAndNil(FResult);
  end;
FResult := FMysql.query('select * from users;', true, ex);
  if assigned(FResult) then
  begin
  FResult.First;
          for j:=0 to FResult.RowsCount-1 do
          begin
          if FResult.FieldValuebyname('status')='online' then
          begin
          //Hier muss die Schrift grün werden
           Listbox3.Items.Insert(0, FResult.FieldValuebyname('login'));
          end
          else
          begin
        //Hier muss die Schrift rot werden
        Listbox3.Items.add(FResult.FieldValuebyname('login'));
          end;
        FResult.Next;
      end;
  end
  else

Jelly 29. Dez 2007 11:04

Re: Farbige Listbox
 
Du hast das Problem, es unbedingt in Onshow Ereignis der Form reinzupacken, da du für die einzelne Einträge in der Listbox der Status (online oder offline) nicht weisst, weil du ja nur den Namen de Login drin speicherst. Im OnDrawItem ist dir also die Information verloren, ob der User online oder offline ist.

Ich würde dir also dringend raten, diese Information ebenfalls zu speichern. Das kannst du, indem du statt Items.Add besser die Methode Items.AddObject nutzt. Dort kannst du, neben der eigentlichen Caption die in der Listbox dargestellt wird, noch ein beliebiges Objekt mitspeichern...

Und dann geht das auch wieder, alles im OnDrawItem Ereignis abzufragen, um zu entscheiden welche Farbe der Eintrag sein soll.

XXcD 29. Dez 2007 11:11

Re: Farbige Listbox
 
Ok ich muss jetzt noch kurz weg, danach schau ich mal ob ich in der scuhe was finde. Vielleicht kann mir ja einer schon einen tip geben, wie das mit addobject geht. Hab damit noch nie gearbeitet :-D

ManfredG 29. Dez 2007 12:21

Re: Farbige Listbox
 
Vielleicht nicht elegant, aber wie wärs mit:

Delphi-Quellcode:
Listbox3.Clear;
if assigned(FResult) then begin
    if FMysql.Status<>MYSQL_STATUS_READY then
      ShowMessage('Ein Ergebnis wurde unvollständig gelesen!');
      FreeAndNil(FResult);
  end;
FResult := FMysql.query('select * from users;', true, ex);
  if assigned(FResult) then
  begin
  FResult.First;
          for j:=0 to FResult.RowsCount-1 do
          begin
          if FResult.FieldValuebyname('status')='online' then
          begin
          //Hier muss die Schrift grün werden
           ListBox3.Items.InsertObject(0, FResult.FieldValuebyname('login'), TObject(clGreen));
          end
          else
          begin
        //Hier muss die Schrift rot werden
           ListBox3.Items.InsertObject(0, FResult.FieldValuebyname('login'), TObject(clRed));
          end;
        FResult.Next;
      end;
  end
  else
Das würde für jede Zeile die Farbe festhalten, im TObject-Zeiger dieser Zeile.
Danach mußt du aber trotzdem OnDrawItem erstellen, damit die Farbe auch dargestellt wird.
Nach der Methode von @Hansa wäre das:

Delphi-Quellcode:
procedure TForm1.ListBox3DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  Listbox3.Canvas.Brush.Color := TColor(ListBox3.Items.Objects[Index]);
  Listbox3.Canvas.FillRect(Rect);
  Listbox3.Canvas.TextOut(Rect.Left, Rect.Top, Listbox3.Items[Index]);
end;
Für ListBox3 - Style auf lbOwnerDrawFixed - stellen.
Gruß Manfred

quendolineDD 29. Dez 2007 12:30

Re: Farbige Listbox
 
Anstatt InsertObject würde ich AddObject nehmen :)
Vergiss nicht Rect.Left+1 und Rect.Top+1

Grüße

XXcD 29. Dez 2007 13:00

Re: Farbige Listbox
 
Jo danke das funtzt wunderbar.
Und ich muss insertobject nehmen, weil die online Player oben erscheinen sollen.

Vielen dank für eure Hilfe und einen Guten Rutsch ins neue Jahr :-D :-D :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:54 Uhr.
Seite 1 von 2  1 2      

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