Listbox dauerhaft farbige Einträge



  • Hi
    Habe 2 ListBox(en) und möchte von der einen per Drag and Drop in die andere Einträge ziehen. Das geht schon.
    Die Einträge sollen je nach Name unterschiedliche Hintergrundfarben haben.
    Das geht auch schon.

    Nur, sobald ich einen neuen Eintrag rüberziehe, bekommt der Eintrag der schon in dieser ListBox ist, die Hintergrundfarben von dem aktuell reingezogenem.
    Und das kann ich nicht verhindern.

    Kann mir bitte jemand helfen.

    Mein Code sieht so aus:

    TColor Colors; //Variable in der die Farbe gespeichert wird
         String Kategorie; 
    
          //Name des per Drag`n`Drop rübergezogenem Eintrag
         titel=lboxSource->Items->Strings[lboxSource->ItemIndex];
         // Eintrag wird in Datenbank gesucht
         Form1->Table1->First();
         for(int i=0; i<Form1->Table1->RecordCount; i++)
         {
            if (Form1->Table1->FieldByName("Titel")->AsString==titel)
            {
               Kategorie=Form1->Table1->FieldByName("Kategorie")->AsString;
            }
         Form1->Table1->Next();
         }
         if (Kategorie=="Landschaft")
         {
            Colors= clRed;
         }
         if (Kategorie=="Kunst")
         {
            Colors= clBlue;
         }
          if(State.Contains(odSelected))
      {
         //Farbe der Schrift
         lboxTarget->Canvas->Brush->Color = Colors;
         //Farbe des Hintergrundes
         lboxTarget->Canvas->Font->Color = clBlack;
         //Text Grösse
         lboxTarget->Canvas->Font->Size = 14;
         //Hintergrund zeichnen
        }
          if(State.Contains(odFocused))
          {
            lboxTarget->Canvas->DrawFocusRect(Rect);
          }
         lboxTarget->Canvas->FillRect(Rect);
         // Text zeichnen
         lboxTarget->Canvas->TextRect(Rect, Rect.Left, Rect.Top,lboxTarget->Items->Strings[Index]);
    


  • Hi,

    Bitte IMMER den Funktionsrumpf einer Methode/Funktion mitposten. Wenn man es nicht macht, kann man sich die Mühe mit der Angabe von Quellcode auch schenken...

    mach eine struct:

    struct TCellObject
    {
    Color BackColor;
    TFont * Font;
    // oder was du sonst noch so brauchst.
    }
    

    nimm für jedes Listbox- Item in der Lines- Eigenschaft eine Instanz dieser Struktur mit auf. ( Über die Eigenschaft Objects).
    Wenn du ein Item rüber schiebst, schiebst du auch das Objekt und damit auch die Instanz von TCellObject.
    In DrawItem fragst du einfach die Instaz ab. Dann wird es etwas übersichtlicher und weniger Fehleransfällig.
    Du kannst auch eine Klasse in den Objects benutzen, die dynamisch werte zurückgibt.



  • Hi
    Danke für deine Antwort, aber wo soll ich dieses Struct einfügen ?!?!?!?

    Der Funktionsaufruf ist

    void __fastcall TForm2::lboxTargetDrawItem(TWinControl *Control, int Index,
          TRect &Rect, TOwnerDrawState State)
    

    Soll das Struct in die Funktion rein und was soll alles umschlossen werden !?!?

    Bitte helft mir 🙂

    Ciao



  • denise schrieb:

    Danke für deine Antwort, aber wo soll ich dieses Struct einfügen ?!?!?!

    AndreasW schrieb:

    nimm für jedes Listbox- Item in der Lines- Eigenschaft eine Instanz dieser Struktur mit auf. ( Über die Eigenschaft Objects). [...]

    (o;

    -junix



  • @junix
    Danke für deine Antwort. Echt SUPER !!!!!!!!!
    @all
    Ich habe dieses Struct in meine Funktion "lboxTargetDrawItem" eingefügt.
    Aber was soll ich jetzt weiter machen ??

    Was bedeutet das und wie geht sowas :

    nimm für jedes Listbox- Item in der Lines- Eigenschaft eine Instanz dieser Struktur mit auf. ( Über die Eigenschaft Objects).
    Wenn du ein Item rüber schiebst, schiebst du auch das Objekt und damit auch die Instanz von TCellObject.

    Wäre für eine konstruktive Hilfe sehr Dankbar.

    Tschüß
    Denise



  • Ich hab m ein Posting überarbeitet und mal den wesentlichen teil fett hervorgehoben.

    junix schrieb:

    denise schrieb:

    Danke für deine Antwort, aber wo soll ich dieses Struct einfügen ?!?!?!

    AndreasW schrieb:

    nimm für jedes Listbox- Item in der Lines- Eigenschaft eine Instanz dieser Struktur mit auf. ( Über die Eigenschaft Objects). [...]

    Du kennst die Eigenschaft "Objects"?

    -junix



  • Also
    Ich habe mein struct
    und dann habe ich in der Funktion eine Instanz erstellt

    TCellObject *instanz;
    

    und es über die Eigenschaft Objects übergeben

    lboxSource->Items->Objects[instanz];
    

    Aber ich bekomme folgende Fehlermeldung
    "Konvertierung von TCellObject nach int nicht möglich" und

    Bitte nicht über mich lachen, aber ich kanns einfach nicht !



  • Niemand lacht. Schau: Schon die erste Aussage ist nicht ganz richtig. Du hast erst einen Zeiger deklariert. Die Instanz erstellst du mit new.

    Das zweite Problem ist folgendes: Objects erwartet einen Wert des Typs int. Was u hier machen musst ist ein cast (reinterpret_cast) deines TCellObjects nach int. Da du hier ja weisst, was du damit machen willst, besteht hier eine AUsnahme der Regel, dass man möglichst nie casten soll. Allerdings musst du natürlich klar deklarieren und dokumentieren, d ass der Wert in Objects nicht dem erwarteten Int sondern einem TCellOBject Zeiger entspricht.

    Ist jetzt etwas kompliziert ausgedrückt, aber ich hoffe du konntest mir folgen (o:

    Wie dem auch sei: Wenn du nun die Instanz erstellt hast, weist du den (gecasteten) Zeiger der Eigenschft "Objects" die am Selben ort steht wie der Eintrag (bei Eintrag 0 also z.B: bei Objects[0]) zu. Wenn du nun die Frabwerte brauchst, kannst du einfach mittels dieses Structs (zurückcasten natürlich) die Frabe auslesen und zeichnen....

    -junix



  • Ich kann kein Objekt erstellen.

    TCellObject instanz= new TCellObject();
    

    Fehler ist Konvertiertung von TCellObject nach TCellObject nicht möglich.
    Vielleicht liegt es daran das es keine Klasse sondern ein struct ist ?!?!

    2tens
    Was meinst du mit Casten.
    soll ich sowas machen :

    instanz = (Integer)instanz;
    

    oder was meinst du mit (reinterpret_cast) ????



  • Instanz erstellen:

    TCellObejcts *instanz= new TCellObjects;
    

    casten:

    int eigentlich_ein_zeiger  =  reinterpret_cast<int>(instanz);
    

    siehe reinterpret_cast in der hilfe.

    -junix



  • Hi
    Habe jetzt die struct erstellt

    struct CellObject
    {
      TColor BackColor;
      TFont * Font;
    }structobject;
    

    und versuche

    void __fastcall TForm2::lboxTargetDrawItem(TWinControl *Control, int Index,
          TRect &Rect, TOwnerDrawState State)
    {
    
         //Variable die den Kategorienamen erhält, um die Hintergrundfarbe zu bestimmen
         String Kategorie;
    
         //Versuch das struct anzuwenden
         CellObject *structobject = new CellObject();
         int eigentlich_ein_zeiger  =  reinterpret_cast<int>(structobject);
    
         //Schleife sucht für den "rübergezogenen" Titel, die Kategorie raus um
         //Hintergrundfarbe zu bestimmen
         Form1->Table1->First();
         for(int i=0; i<Form1->Table1->RecordCount; i++)
         {
            if ( (Form1->Table1->FieldByName("Titel")->AsString) == (lboxSource->Items->Strings[lboxSource->ItemIndex]))
            {
               Kategorie=Form1->Table1->FieldByName("Kategorie")->AsString;
            }
         Form1->Table1->Next();
         }
    
         //Je nach Kategorie bekommt der Eintrag seine Hintergrundfarbe
         //Speicherung mit struct
         if (Kategorie=="Bild")
         {  
            //BackColor von struct wird nicht gefunden  
            eigentlich_ein_zeiger->BackColor= clRed;
         }
         if (Kategorie=="Kunst")
         {
            eigentlich_ein_zeiger,Color= clBlue;
         }
         if (Kategorie=="Landschaft")
         {
            eigentlich_ein_zeiger,Color= clGreen;
         }
    
          //Der Ausgewählte Eintrag bekommt Werte
          if(State.Contains(odSelected))
          {
               //Farbe der Schrift
               lboxTarget->Canvas->Brush->Color = eigentlich_ein_zeiger,Color;
               //Farbe des Hintergrundes
               lboxTarget->Canvas->Font->Color = clBlack;
               //Text Grösse
               lboxTarget->Canvas->Font->Size = 14;
               lboxTarget->Canvas->FillRect(Rect);
         // Text zeichnen
         lboxTarget->Canvas->TextRect(Rect, Rect.Left, Rect.Top,lboxTarget->Items->Strings[Index]);
          }
    
          //Der Eintrag wird gezeichnet
          if(State.Contains(odFocused))
          {
            lboxTarget->Canvas->DrawFocusRect(Rect);
          }
         lboxTarget->Canvas->FillRect(Rect);
         // Text zeichnen
         lboxTarget->Canvas->TextRect(Rect, Rect.Left, Rect.Top,lboxTarget->Items->Strings[Index]);
    
    }
    

    im if-Bereich die Farbe im struct zu speichern.
    Aber dann ändert sich immer die Hintergrundfarbe des Formulars.
    Ich habe in der 1 ten if versucht direkt auf die Struct Variable BackColor zuzugreifen aber das geht nicht.

    So schwer kann das doch nicht sein oder ????
    Bin echt am Verzeweifeln. Sowas muss doch schon mal jemand gemacht haben.
    Bitte euch nochmal um Hilfe

    Tschö
    Denise


Anmelden zum Antworten