![]() |
TComboBox mit Aliaswerten
Ich hätt da maln Problem...
Wenn man mit einer ComboBox (Stringlisten) arbeitet, so hat man meiner Meinung nach den unschönen Zustand, das als Selektionsergebnis (kein Multiselekt) quasi nur die Eigenschaft "Text" oder ItemIndex zur Verfügung steht. Insbesondere ItemIndex ist sehr unschön, da es den Index des Eintrages liefert. Dies ist solange kein wirkliches Problem, solange man die Liste am Ende um neue Werte ergänzt. Aber spätestens, wenn der Anwender die Liste sortiert haben möchte, und man den Index gespeichert hat, hat man ein ernstes Problem. Speichert man hingegen den Text selbst und nicht den Index, so bekommt man schnell beim Thema "Mehrsprachigkeit" wiederum ein ernstes Problem. Viel sinniger wäre in meinen Augen, die Werteliste mit Aliaswerten anzureichern, die nicht den Index wiederspiegeln. Also statt: "Banane" 0 "Apfel" 1 "Kirsche" 2 "Erdbeere" 3 besser: "Banane" "0" "Apfel" "1" "Kirsche" "2" "Erdbeere" "3" Items: "Banane=0" "Apfel=1" "Kirsche=2" "Erdbeere=3" Die Eigneschaft "Text" würde bei gewähltem Eintrag "Apfel" auch "Apfel" lauten, und ItemIndex 1, die (fehlende) Eigenschaft TextAlias oder ItemAlias müsste "1" liefern. Und wenn man diese Eigenschaft setzt, müsste die Komponente den entsprechenden Wert auch als ausgewählt anzeigen (Eigenschaften Text und ItemIndex müssen entsprechend gesetzt werden). Kennt jemand eine Combobox Komponente, die genau so was kann? Oder hat jemand eine Idee, wie man dies auf Basis der Delphi Standardkomponenten bauen könnte? |
AW: TComboBox mit Aliaswerten
Pack doch Deine Aliaswerte in eine Klasse, die Du dann mit AddObject den Items der ComboBox hinzufügst.
|
AW: TComboBox mit Aliaswerten
Nunja, die Idee mit AddObject hatte ich auch schon, aber da fehlt mir eine Menge an "Komfort" und es müsste noch einiges gebaut werden, andernfalls müsste dann jedesmal wieder was gebaut werden.
Eine Komponente, die einfach zu verwenden wäre, ist da schon eher mein Ding. Leider stecke ich in der VCL nicht so wirklich tief drin (Delphi 2007) und tue mir da schwer. Trotzdem habe ich einmal einen absolut nicht funktionierenden "Rumpf" gebaut. Jeder Versuch der Klasse ein Item oder eine Liste hinzuzufügen scheitert. Das erste Problem hierbei scheint wohl, das die Items vom Type TStrings sind und nicht vom Typ TStringList (wie ich erwartet hätte. Wo sind die dann gespeichert?) - also keine Werte selbst halten. Die zweite Schwierigkeit ist, das Objekte, die der Liste hinzugefügt werden, auch selbst wieder gelöscht werden müssen (laut Doku).
Delphi-Quellcode:
unit AliasComboBox;
interface uses SysUtils, Classes, Controls, StdCtrls; type TAliasComboBox = class( TCustomComboBox ) private { Private-Deklarationen } protected { Protected-Deklarationen } function GetItemsClass: TCustomComboBoxStringsClass; override; procedure SetItems( const Value: TStrings ); override; function GetItemAlias: String; procedure SetItemAlias( sAlias: String ); public { Public-Deklarationen } published { Published-Deklarationen } property Align; property AutoComplete default True; property AutoCompleteDelay default 500; property AutoDropDown default False; property AutoCloseUp default False; property BevelEdges; property BevelInner; property BevelKind default bkNone; property BevelOuter; property Style; {Must be published before Items} property Anchors; property BiDiMode; property CharCase; property Color; property Constraints; property Ctl3D; property DragCursor; property DragKind; property DragMode; property DropDownCount; property Enabled; property Font; property ImeMode; property ImeName; property ItemAlias: String read GetItemAlias write SetItemAlias; property ItemHeight; property ItemIndex default -1; property MaxLength; property ParentBiDiMode; property ParentColor; property ParentCtl3D; property ParentFont; property ParentShowHint; property PopupMenu; property ShowHint; property Sorted; property TabOrder; property TabStop; property Text; property Visible; property OnChange; property OnClick; property OnCloseUp; property OnContextPopup; property OnDblClick; property OnDragDrop; property OnDragOver; property OnDrawItem; property OnDropDown; property OnEndDock; property OnEndDrag; property OnEnter; property OnExit; property OnKeyDown; property OnKeyPress; property OnKeyUp; property OnMeasureItem; property OnMouseEnter; property OnMouseLeave; property OnSelect; property OnStartDock; property OnStartDrag; property Items; { Must be published after OnMeasureItem } end;//of class procedure Register; implementation //============================================================================== procedure Register; begin RegisterComponents( 'Beispiele', [ TAliasComboBox ]); end;//of procedure //======================================================================== Types type TAliasComboBoxStrings = class( TCustomComboBoxStrings ) public procedure Delete(Index: Integer); override; end;//of class type TAlias = class( TObject ) private { Private-Deklarationen } FAlias: String; protected { Protected-Deklarationen } public { Public-Deklarationen } constructor CreateAlias( sAlias: String ); virtual; published { Published-Deklarationen } property Alias: String read FAlias; end;//of class //======================================================== TAliasComboBoxStrings procedure TAliasComboBoxStrings.Delete( Index: Integer ); var aObj: TObject; begin if( 0 > Index ) then //Do nothing else begin //Löschen des erzeugten Objektes aObj:= GetObject( Index ); aObj.Free; aObj := nil; PutObject( Index, aObj ); end;//of if inherited Delete( Index ); end;//of procedure //======================================================================= TAlias constructor TAlias.CreateAlias( sAlias: String ); begin inherited Create(); FAlias := sAlias; end;//of constructor //=============================================================== TAliasComboBox function TAliasComboBox.GetItemsClass: TCustomComboBoxStringsClass; begin Result := TAliasComboBoxStrings; end;//of function //------------------------------------------------------------------------------ procedure TAliasComboBox.SetItems( const Value: TStrings ); var iCount: Integer; begin inherited SetItems( Value ); if( not Assigned( Value )) then //Do nothing else if( 0 >= Value.Count ) then //Do nothing else begin for iCount := 0 to Value.Count - 1 do begin Items.Objects[ iCount ]:= TAlias.CreateAlias( Trim( Value.ValueFromIndex[ iCount ])); Items.Strings[ iCount ]:= Trim( Items.Names[ iCount ]); end;//of for end;//of else end;//of procedure //------------------------------------------------------------------------------ function TAliasComboBox.GetItemAlias: String; begin if( 0 > ItemIndex ) then Result := '' else Result := TAlias( Items.Objects[ ItemIndex ]).Alias; end;//of function //------------------------------------------------------------------------------ procedure TAliasComboBox.SetItemAlias( sAlias: String ); var bDoChg: Boolean; iCount: Integer; begin if( 0 > ItemIndex ) then bDoChg:= True else if( sAlias <> TAlias( Items.Objects[ ItemIndex ]).Alias ) then bDoChg:= True else bDoChg:= False; if( bDoChg ) then begin for iCount := 0 to Items.Count - 1 do begin if( 0 = CompareText( sAlias, TAlias( Items.Objects[ ItemIndex ]).Alias )) then begin ItemIndex := iCount; Text := Items[ iCount ]; Break;//of for end;//of for end;//of for end;//of if end;//of procedure end. |
AW: TComboBox mit Aliaswerten
Du gehst das von der falschen Seite an ;)
Erstelle dir eine ObjektListe mit allen benötigten Informationen:
Wenn jetzt sortiert werden soll, dann sortierst du die Liste und fängst von vorne an (Label-Text in ComboBox) |
AW: TComboBox mit Aliaswerten
Der Tipp mit der Objektliste war super. Danke dafür.
Hier die Version 1.0 (Anmerkungen und Verbesserungen bitte hier posten):
Delphi-Quellcode:
unit AliasComboBox;
interface uses SysUtils, Classes, Controls, StdCtrls, Contnrs; type TAliasObj = class( TObject ) private { Private-Deklarationen } FLabel: String; FValue: String; protected { Protected-Deklarationen } public { Public-Deklarationen } constructor CreateAlias( sLabel, sValue: String ); virtual; published { Published-Deklarationen } property Value: String read FLabel; property Alias: String read FValue; end;//of class type TAliasComboBox = class( TCustomComboBox ) private { Private-Deklarationen } FAliasList: TObjectList; protected { Protected-Deklarationen } function GetAliasForLabel( sLabel : String ): String; function GetLabelForAlias( sAlias : String ): String; function GetItemAlias : String; procedure SetItemAlias ( sAlias : String ); procedure AddSingleItemVal( sValue : String ); procedure AddItem ( Item : String; aObject: TObject ); override; procedure SetItems ( const Value : TStrings ); override; public { Public-Deklarationen } constructor Create ( aOwner : TComponent ); override; destructor Destroy; override; procedure Clear; override; procedure AddAliasItem ( sLabel : String; sValue : String ); virtual; procedure AddAliasStrings( aList : TStrings ); virtual; published { Published-Deklarationen } property Align; property AutoComplete default True; property AutoCompleteDelay default 500; property AutoDropDown default False; property AutoCloseUp default False; property BevelEdges; property BevelInner; property BevelKind default bkNone; property BevelOuter; property Style; {Must be published before Items} property Anchors; property BiDiMode; property CharCase; property Color; property Constraints; property Ctl3D; property DragCursor; property DragKind; property DragMode; property DropDownCount; property Enabled; property Font; property ImeMode; property ImeName; property ItemAlias: String read GetItemAlias write SetItemAlias; property ItemHeight; property ItemIndex default -1; property MaxLength; property ParentBiDiMode; property ParentColor; property ParentCtl3D; property ParentFont; property ParentShowHint; property PopupMenu; property ShowHint; property Sorted; property TabOrder; property TabStop; property Text; property Visible; property OnChange; property OnClick; property OnCloseUp; property OnContextPopup; property OnDblClick; property OnDragDrop; property OnDragOver; property OnDrawItem; property OnDropDown; property OnEndDock; property OnEndDrag; property OnEnter; property OnExit; property OnKeyDown; property OnKeyPress; property OnKeyUp; property OnMeasureItem; property OnMouseEnter; property OnMouseLeave; property OnSelect; property OnStartDock; property OnStartDrag; property Items; { Must be published after OnMeasureItem } end;//of class procedure Register; implementation //============================================================================== procedure Register; begin RegisterComponents( 'Beispiele', [ TAliasComboBox ]); end;//of procedure //==================================================================== TAliasObj constructor TAliasObj.CreateAlias( sLabel, sValue: String ); begin inherited Create(); FLabel:= sLabel; FValue:= sValue; end;//of constructor //=============================================================== TAliasComboBox constructor TAliasComboBox.Create( aOwner: TComponent ); begin inherited Create( aOwner ); FAliasList:= TObjectList.Create; end;//of constuctor //------------------------------------------------------------------------------ destructor TAliasComboBox.Destroy; begin if( Assigned( FAliasList )) then FAliasList.Free; inherited Destroy; end;//of destructor //------------------------------------------------------------------------------ procedure TAliasComboBox.Clear; begin if( Assigned( FAliasList )) then FAliasList.Clear; inherited Clear; end;//of procedure //------------------------------------------------------------------------------ procedure TAliasComboBox.AddAliasItem( sLabel, sValue: String ); begin if( Assigned( FAliasList )) then FAliasList.Add( TAliasObj.CreateAlias( sLabel, sValue )); Items.Add( sLabel ); end;//of procedure //------------------------------------------------------------------------------ procedure TAliasComboBox.AddAliasStrings( aList: TStrings ); var iCount: Integer; begin if( Assigned( FAliasList )) then FAliasList.Clear; Items.Clear; if( Assigned( aList )) then begin Items.BeginUpdate; for iCount := 0 to aList.Count - 1 do begin AddSingleItemVal( aList.Strings[ iCount ]); end;//of for Items.EndUpdate; end;//of if end;//of procedure //------------------------------------------------------------------------------ function TAliasComboBox.GetAliasForLabel( sLabel: String ): String; var iCount: Integer; iPos : Integer; begin Result := ''; sLabel := Trim( sLabel ); if( '' <> sLabel ) then begin iPos := Pos( Items.NameValueSeparator, sLabel ); if( 0 < iPos ) then sLabel := Trim( Copy( sLabel, 1, iPos - 1 )); Result := sLabel; if( Assigned( FAliasList )) then begin for iCount := 0 to FAliasList.Count - 1 do begin if( 0 = CompareText( sLabel, TAliasObj( FAliasList.Items[ iCount ]).FLabel )) then begin Result:= TAliasObj( FAliasList.Items[ iCount ]).FValue; Break;//of for end;//of if end;//of for end;//of if end;//of if end;//of function //------------------------------------------------------------------------------ function TAliasComboBox.GetLabelForAlias( sAlias: String ): String; var iCount: Integer; begin Result := ''; sAlias := Trim( sAlias ); if( '' <> sAlias ) then begin if( not Assigned( FAliasList )) then Result := sAlias else begin for iCount := 0 to FAliasList.Count - 1 do begin if( 0 = CompareText( sAlias, TAliasObj( FAliasList.Items[ iCount ]).FValue )) then begin Result:= TAliasObj( FAliasList.Items[ iCount ]).FLabel; Break;//of for end;//of if end;//of for end;//of else end;//of if end;//of function //------------------------------------------------------------------------------ function TAliasComboBox.GetItemAlias: String; begin if( 0 > ItemIndex ) then Result := '' else Result := GetAliasForLabel( Items.Strings[ ItemIndex ] ); end;//of function //------------------------------------------------------------------------------ procedure TAliasComboBox.SetItemAlias( sAlias: String ); var bDoChg: Boolean; sLabel: String; iIndex: Integer; begin if( 0 > ItemIndex ) then bDoChg:= True else if( ItemAlias <> sAlias ) then bDoChg:= True else bDoChg:= False; if( bDoChg ) then begin iIndex:= Items.IndexOf( GetLabelForAlias( sAlias )); if( 0 > iIndex ) then //Do nothing else begin ItemIndex := iIndex; Text := Items[ iIndex ]; end;//of else end;//of if end;//of procedure //------------------------------------------------------------------------------ procedure TAliasComboBox.AddSingleItemVal( sValue: String ); var iPos: Integer; begin iPos := Pos( Items.NameValueSeparator, sValue ); if( 0 < iPos ) then AddAliasItem( Trim( Copy( sValue, 1, iPos - 1 )), Trim( Copy( sValue, iPos + 1, Length( sValue ) - iPos ))) else AddAliasItem( Trim( sValue ), Trim( sValue )); end;//of procedure //------------------------------------------------------------------------------ procedure TAliasComboBox.AddItem( Item: String; aObject: TObject ); begin inherited AddItem( Item, aObject ); AddSingleItemVal( Item ); end;//of procedure //------------------------------------------------------------------------------ procedure TAliasComboBox.SetItems( const Value: TStrings ); begin AddAliasStrings( Value ); end;//of procedure end. |
AW: TComboBox mit Aliaswerten
Zitat:
PS: Sowas nennen viele eine LookupComboBox und die gibt es schon fertig. (in Delphi selber allerdings nur in der datensensitiven Variante) |
AW: TComboBox mit Aliaswerten
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz