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/)
-   -   ComboBox mit Integer-IDs (https://www.delphipraxis.net/211392-combobox-mit-integer-ids.html)

e-gon 9. Sep 2022 12:30

ComboBox mit Integer-IDs
 
Hallo zusammen,

ich arbeite gerne mit ComboBoxen. Allerdings stehe ich immer wieder vor dem Problem, dass ich nicht nur eine Sting-Liste benötige, sondern zusätzlich noch eine ID, die oft nicht mit ItemIndex übereinstimmt.

Wenn ich beispielsweise Daten sortiert aus einer Datenbank lese, wäre es oft praktisch mit dem Text auch gleich den Index des Datensatzes zu haben, statt diesen erst mit einer zusätzlichen Abfage über den Text zu ermitteln.

Deshalb schrieb ich diese eigene kleine Komponente:

Delphi-Quellcode:
unit BaBiCtrls2;

interface

  uses
    StdCtrls, Classes;

  type
  { TIdComboBox }

    TIdComboBox = class(TComboBox)
    private
      FIds: TList;
      procedure SetId(Index,Id: Integer);
      function GetId(Index: Integer): Integer;
    public
      constructor Create(AOwner: TComponent); override;
      destructor Destroy; override;
      procedure AddIdItem(const s: string; const Id: Integer);
      property Id[Index: Integer]: Integer read GetId write SetId;
    end;


  procedure Register;


implementation

  procedure Register;
  begin
    RegisterComponents('BaBi', [TIdComboBox]);
  end;


  { TIdComboBox }

  constructor TIdComboBox.Create(AOwner: TComponent);
  begin
    inherited Create(AOwner);
    FIds:= TList.Create;
  end;

  destructor TIdComboBox.Destroy;
  begin
    FIds.Free;
    inherited;
  end;

  function TIdComboBox.GetID(Index: Integer): Integer;
  begin
    if Index<FIds.Count then
      Result:= Integer(FIds[Index])
    else
      Result:= 0;
  end;

  procedure TIdComboBox.SetId(Index: Integer; Id: Integer);
  begin
    while Index>=FIds.Count do FIds.Add(Pointer(0));

    if Id <> GetId(Index) then
    begin
      FIds[Index]:= Pointer(Id);
    end;
  end;

  procedure TIdComboBox.AddIdItem(const s: string; const Id: Integer);
  var Index: Integer;
  begin
    Index:= Items.Count;
    Items.AddObject(s,TObject(Self));
    SetId(Index,Id);
  end;

end.
Generell tut sie, was ich will. Allerdings habe ich das Problem, wenn direkte Operationen über die String-Liste (ComboBox1.Items) durchgeführt werden. Add ist ja kein Problem, aber Insert, Delete, Sort,... - eben alles, was die Reihenfolge beeinflusst.

Kann mir jemand sagen, wie ich diese Operationen abfangen kann oder zumindest mitbekomme, dass sowas ausgeführt wurde?

Gruß
e-gon

himitsu 9. Sep 2022 12:46

AW: ComboBox mit Integer-IDs
 
Wozu das Self im AddObject? (und auch noch unnötig nach TObject gekastet)

Die Windows-Komponente kennt eh keine Objekte ... dort ist das "Objekt" eigentlich "Data" und das ist ein dummer Pointer/Integer.

Fazit:
* Caste einfach deinen Integer nach TObject (nimm besser gleich NativeInt anstatt Integer, damit es eventuell irgendann unter 64 Bit nicht rumzickt)
* beim Lesen einfach den Integer wieder aus Objects lesen
* * also quasi ganz einfach nur AddIdItem zu Items.AddObject und ID[] zu Items.Objects casten/weiterleiten
* und das Ganze Zeugs mit der zusätzlichen Liste sein lassen.

Alternativ ein DataObjekt erstellen, das an Objects übergeben (und nicht vergessen das wieder freizugeben, denn da es in Wirklichkeit keine Objekt-Zeiger sind und Delphi/VCL diese "Objekte" auch nicht aufräumt ... mußt du das machen)


Ansonsten hast Spaß eben, wenn du Items löschst, verschiebst/sortierst, was Insertest usw.,
weil du nicht auf das OnChange reagierst und deine interne Liste damit abgleichst.



TComboBox und TListBox sind das Selbe. (ich glaub TRadioGroupBox auch)
Achtung, bei TMemo gibt es auch ein Objekts, aber das wird intern nirgendwo gespeichert (und natürlich hat Delphi/VCL vergessen dort eine Exception einzubauen, falls man es dennoch versucht)


Delphi 6?
Wenn aktueller, dann kannst dir die Ableitung/Registrierung sparen,
erstellst einfach einen ClassHelper und hast das Verhalten direkt an jeder normalen TComboBox verfügbar.
(in D6 kann man aber auch "gleichnamig" ableiten und muß nicht registrieren, da der Speicher der Klasse unverändert bleibt)
Bei Google suchencommunity edition

e-gon 9. Sep 2022 13:23

AW: ComboBox mit Integer-IDs
 
Hallo himitsu,

vielen Dank für die schnelle Antwort!

Auf die Idee das TObject zum Speichern meiner ID zu verwenden bin ich natürlich nicht gekommen...

Danke!

Gruß
e-gon

Uwe Raabe 9. Sep 2022 14:10

AW: ComboBox mit Integer-IDs
 
Bei neueren Delphi-Versionen könnte man so was auch mit einem Class Helper realisieren. Das funktioniert dann mit jeder TComboBox.
Delphi-Quellcode:
type
  TComboBoxHelper = class helper for TComboBox
  private
    procedure SetId(Index, Id: Integer);
    function GetId(Index: Integer): Integer;
  public
    function AddIdItem(const s: string; const Id: Integer): Integer;
    property Id[Index: Integer]: Integer read GetId write SetId;
  end;

function TComboBoxHelper.AddIdItem(const s: string; const Id: Integer): Integer;
begin
  Result := Items.AddObject(s, TObject(Id));
end;

function TComboBoxHelper.GetId(Index: Integer): Integer;
begin
  Result := Integer(Items.Objects[Index]);
end;

procedure TComboBoxHelper.SetId(Index, Id: Integer);
begin
  Items.Objects[Index] := TObject(Id);
end;

TUhr 9. Sep 2022 15:37

AW: ComboBox mit Integer-IDs
 
Hallo,

ich hatte mal ein ähliches Problem. Ich habe es damals wie folgt gelöst :
Ich habe die ersten 9 Zeichen des Strings sind die Zahlen-ID.
Der restliche Teil des Strings war die Zeichenkette.
Im Event OnDrawItem habe ich dann nur die Zeichenkette ausgeben lassen.....

Mfg
Thorsten

banaguitar 5. Apr 2024 08:04

AW: ComboBox mit Integer-IDs
 
Hallo, auch, wenn der Beitrag schon älter ist, hier eine ähnliche Frage. Wie mache ich das mit mehreren zur Laufzeit unbekannten Anzahl von TImage32-Komponenten? Ich habe Delphi 12.
Da muss ich für jedes Bild die entsprechende ID und den Pfadnamen aus der Datenbanken mittracken, da ich die Daten zwecks Bearbeitung der Bilder benötige, um sie nachher in der Datenbank zu aktualisieren.

omnibrain 5. Apr 2024 08:26

AW: ComboBox mit Integer-IDs
 
Wenn ich das richtig gesehen habe ist bei den Raize Components so eine ComboBox dabei.

Olli73 5. Apr 2024 09:03

AW: ComboBox mit Integer-IDs
 
Du brauchst doch eigentlich nur eine Klasse (oder Record) in der Form:

Delphi-Quellcode:
TMyImage = class
  ID: Integer;
  Path: string;
end;
Und dann erzeugst du pro Image ein Objekt davon und machst ein AddObject zu dem entsprechenden Item der ComboBox.

banaguitar 5. Apr 2024 09:32

AW: ComboBox mit Integer-IDs
 
Hi, alles klar, danke Dir, eine Combobox brauche ich aber nicht. Wenn man auf das jeweilige Bild klickt, soll sich ein neues Formular öffnen, wo man dann weitere Bearbeitungen daran vornehmen kann. Das ist aber kein Problem. Mein Problem ist nur, dass ich mir ja die Daten wie ID, path usw. von dem Bild/TImage32 merken und zuordnen muss.

Sinspin 5. Apr 2024 11:14

AW: ComboBox mit Integer-IDs
 
Zitat:

Zitat von banaguitar (Beitrag 1535359)
... , eine Combobox brauche ich aber nicht. ...

Das kommt davon wenn man alte Posts aufwärmt. Da muss man damit leben das die Antworten nicht wirklich passen.

Hier gehts weiter : daten aus datenbank zu timage32 komponenten hinzufuegen


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