![]() |
TcxCheckComboBoxProperties und veränderliche Items
Moin,
ich hab hier ein TcxGridDBBandedTableView und bei einer Spalte (TcxGridDBBandedColumn) ist als Properties die CheckComboBox eingestellt. In dem StringField befinden sich nun Kommagetrennte Texte, welche ich darüber auswählbar machen wollte. Diese möglichen Texte unterscheiden sich aber, jenachdem, was in einer anderen Spalte/Field drinsteht. Nun lade ich also im Record-Change die passenden Items in CheckComboBox.Items rein, was auch funktioniert, allerdings werden dabei nicht nur die Items der ComboBox, sondern auch die Anzeigetexte der anderen Records verändert (entsprechend ihrem ItemIndex). :shock: EditValueFormat = cvfStatesString und Delimitter = , Auch läßt sich bei dem Ding der Text nicht mehr manuell eingeben, sondern nur noch über die CheckBoxen. (Beim TcxComboBoxProperties funktioniert es perfekt, also nur die Items der ComboBox werden angepasst, aber die Texte der anderen Records bleiben unangetastet) [edit] Ich hab nun auch mal geschaut was das Ding wirklich speichert und aus f2_id, f2_uniquekey und vartxtnr macht es ... cvfCaptions = ";5:f2_id12:f2_uniquekey8:vartxtnr" cvfIndices = ";1,3,6" cvfInteger = "74" cvfStatesString = "0101001000000000000000000000000" Aber (zumindestens da wo auch die "richtigen" Items geladen sind) zeigt mir das Ding "f2_id,f2_uniquekey,vartxtnr" zumindestens in der GUI an ... ich will das aber auch so im Feld gespeichert haben und nicht daß die Anzeige dadurch beeinflusst wird. :wall: Im Prinzip suche ich doch nur eine art Multiselect ComboBox, welche mir die ausgewählten Werte kommagetrennt ins Feld schreibt. :cry: Kennt da jemand eine Lösung? |
AW: TcxCheckComboBoxProperties und veränderliche Items
Hab nach langem Suchen geheime Events gefunden (geheim = die sind nicht im OI sichtbar)
und angefangen diese zu benutzen.
Delphi-Quellcode:
Was so erstmal nicht geht, dann irgendwer ist auf die saublöde Idee gekommen und läßt den Sender leer (nil).
procedure TFormSyncro2.ValueToCheckStatesEvent(Sender: TObject; const AValue: TcxEditValue; var ACheckStates: TcxCheckStates);
var i: Integer; SL: TStringList; begin if VarIsNull(AValue) then begin for i := 0 to High(ACheckStates) do ACheckStates[i] := cbsChecked; Exit; end; SL := TStringList.Create; try SL.CommaText := AValue; for i := 0 to High(ACheckStates) do if SL.IndexOf(((Sender as TcxCheckComboBoxProperties).Items[i] as TcxCheckComboBoxItem).Description) >= 0 then ACheckStates[i] := cbsChecked else ACheckStates[i] := cbsUnchecked; finally SL.Free; end; end; procedure TFormSyncro2.CheckStatesToValueEvent(Sender: TObject; const ACheckStates: TcxCheckStates; out AValue: TcxEditValue); var S: string; i: Integer; begin S := ''; for i := 0 to High(ACheckStates) do if ACheckStates[i] = cbsChecked then S := S + IfThen(S <> '', ',', '') + TcxCheckComboBoxItem((Sender as TcxCheckComboBoxProperties).Items[i]).Description; if S <> '' then AValue := S else AValue := NULL; end; Soll man das etwa für jedes Feld das einzeln implementieren? :wall: |
AW: TcxCheckComboBoxProperties und veränderliche Items
Manchmal denk ich mir, die haben nicht mehr alle Gläser im Schrank.
Schon schlimm, was man alles umbiegen muß, nur um den Feldtext anders zu verarbeiten, dabei gibt es "eigentlich", OnEditValueToStates und OnStatesToEditValue, aber da intern oftmals einfach direkt auf die Basiskonvertierungsfunktion gegangen wird, anstatt über die Methoden und da auch noch bei dem Klassenwirrwar die Objekte vergessen, von wem sie erstellt wurden und dann einfach wieder auf die Ursprungsklasse zurückgehn ........... Ja, und dann sind diese Ereignisse in den virtuellen CalculateCheckStatesByEditValue und CalculateEditValueByCheckStates gekapselt, aber leider wird auf überschriebene Metoden an einigen Stellen nicht reagiert, sondern nur auf die OnDinger, womit dann plötzlich wieder auf die Standardroutinen zurückgegangen wird ... Nja, nach leichter Verzweiflung und viel sinnlosem Abgeleite, hab ich nun endlich das, was ich wollte. :angle: - der Text ist in der Vorschau genauso, wie die Daten im Feld - es wird direkt mit den kommaseparierten Captions gearbeitet - alle Zeilen sind nun unabhängig voneinander was aber noch nicht geht - man kann den Text nicht direkt editieren - eventuell kann man auch noch "unbekannte" Captions beibehalten, denn wenn was nicht in der Liste enthalten ist, dann verschwindet es beim Editieren, was etwas problematisch sein kann, da man eben auch noch nicht manuell editieren kann (aber für Letzteres denk ich mal, hab ich eine Lösung)
Delphi-Quellcode:
type
TRealCheckComboBoxProperties = class(TcxCheckComboBoxProperties) constructor Create(Owner: TPersistent); override; function IsDelimiterStored: Boolean; function IsEmptySelectionTextStored: Boolean; property EditValueFormat default cvfCaptions; property Delimiter stored IsDelimiterStored; property EmptySelectionText stored IsEmptySelectionTextStored; property ShowEmptyText default False; procedure PrepareDisplayValue(const AEditValue: TcxEditValue; var DisplayValue: TcxEditValue; AEditFocused: Boolean); override; class function GetLookupDataClass: TcxInterfacedPersistentClass; override; class function GetPopupWindowClass: TcxCustomEditPopupWindowClass; override; class function GetViewDataClass: TcxCustomEditViewDataClass; override; class function GetContainerClass: TcxContainerClass; override; procedure CalculateCheckStatesByEditValue(Sender: TObject; const AEditValue: TcxEditValue; var ACheckStates: TcxCheckStates); override; function CalculateEditValueByCheckStates(Sender: TObject; const ACheckStates: TcxCheckStates): TcxEditValue; override; function CalculateDisplayValueByCheckStates(const ACheckStates: TcxCheckStates): string; override; end; TRealCustomCheckComboBoxViewData = class(TcxCustomCheckComboBoxViewData) function InternalEditValueToDisplayText(AEditValue: TcxEditValue): string; override; end; TRealCheckComboBoxLookupData = class(TcxCheckComboBoxLookupData) function GetListBoxClass: TcxCustomEditListBoxClass; override; end; TRealCustomCheckComboBoxListBox = class(TcxCustomCheckComboBoxListBox) end; TRealCheckComboBox = class(TcxCheckComboBox) class function GetPropertiesClass: TcxCustomEditPropertiesClass; override; end; implementation constructor TRealCheckComboBoxProperties.Create(Owner: TPersistent); begin inherited; EditValueFormat := cvfCaptions; Delimiter := ','; EmptySelectionText := ''; ShowEmptyText := False; end; function TRealCheckComboBoxProperties.IsDelimiterStored: Boolean; begin Result := Delimiter <> ','; end; function TRealCheckComboBoxProperties.IsEmptySelectionTextStored: Boolean; begin Result := EmptySelectionText <> ''; end; procedure TRealCheckComboBoxProperties.PrepareDisplayValue(const AEditValue: TcxEditValue; var DisplayValue: TcxEditValue; AEditFocused: Boolean); begin // zusätzlich die CheckStates befüllen CalculateCheckStatesByEditValue(nil, AEditValue, CheckStates); DisplayValue := AEditValue; end; class function TRealCheckComboBoxProperties.GetLookupDataClass: TcxInterfacedPersistentClass; begin Result := TRealCheckComboBoxLookupData; end; class function TRealCheckComboBoxProperties.GetPopupWindowClass: TcxCustomEditPopupWindowClass; begin Result := TcxCheckComboBoxPopupWindow; end; class function TRealCheckComboBoxProperties.GetViewDataClass: TcxCustomEditViewDataClass; begin Result := TRealCustomCheckComboBoxViewData; end; class function TRealCheckComboBoxProperties.GetContainerClass: TcxContainerClass; begin Result := TRealCheckComboBox; end; procedure TRealCheckComboBoxProperties.CalculateCheckStatesByEditValue(Sender: TObject; const AEditValue: TcxEditValue; var ACheckStates: TcxCheckStates); var i: Integer; SL: TStringList; begin SetLength(ACheckStates, Items.Count); if VarIsNull(AEditValue) then begin for i := 0 to High(ACheckStates) do ACheckStates[i] := cbsUnchecked; Exit; end; SL := TStringList.Create; try SL.CommaText := AEditValue; for i := 0 to High(ACheckStates) do if SL.IndexOf(Items[i].Description) >= 0 then ACheckStates[i] := cbsChecked else ACheckStates[i] := cbsUnchecked; finally SL.Free; end; end; function TRealCheckComboBoxProperties.CalculateEditValueByCheckStates(Sender: TObject; const ACheckStates: TcxCheckStates): TcxEditValue; var S: string; i: Integer; begin S := ''; for i := 0 to High(ACheckStates) do if ACheckStates[i] = cbsChecked then S := S + IfThen(S <> '', ',', '') + Items[i].Description; if S <> '' then Result := S else Result := NULL; end; function TRealCheckComboBoxProperties.CalculateDisplayValueByCheckStates(const ACheckStates: TcxCheckStates): string; var V: Variant; begin V := CalculateEditValueByCheckStates(Self, ACheckStates); if VarIsNull(V) then Result := '' else Result := V; end; function TRealCustomCheckComboBoxViewData.InternalEditValueToDisplayText(AEditValue: TcxEditValue): string; var ASender: TObject; begin // zusätzlich die CheckStates befüllen if IsInplace then ASender := nil else ASender := Edit; TRealCheckComboBoxProperties(Properties).CalculateCheckStatesByEditValue(ASender, AEditValue, CheckStates); if VarIsNull(AEditValue) then Result := '' else Result := AEditValue; Properties.DisplayValueToDisplayText(Result); end; function TRealCheckComboBoxLookupData.GetListBoxClass: TcxCustomEditListBoxClass; begin Result := TRealCustomCheckComboBoxListBox; end; class function TRealCheckComboBox.GetPropertiesClass: TcxCustomEditPropertiesClass; begin Result := TRealCheckComboBoxProperties; end; initialization GetRegisteredEditProperties.Register(TRealCheckComboBoxProperties, 'RealCheckComboBox|eine funktionierende ComboBox mit Checkboxen'); FilterEditsController.Register(TRealCheckComboBoxProperties, TcxFilterCheckComboBoxHelper); finalization FilterEditsController.Unregister(TRealCheckComboBoxProperties, TcxFilterCheckComboBoxHelper); GetRegisteredEditProperties.Unregister(TRealCheckComboBoxProperties); |
AW: TcxCheckComboBoxProperties und veränderliche Items
Kennst Du das Event OnGetPropertiesForEdit?
Damit solltest Du deine individuellen Geschichten hinbekommen. Denke nur dran, das die standard TcxCheckComboBoxProperty alle möglichen Einträge enthält, damit die Spalten richtig angezeigt werden. Willst Du eine Zelle editieren, wird vorher OnGetPropertiesForEdit aufgerufen. Hier erzeugst Du (oder hast einen Pool) deine individuellen Properties sammt Itemsliste. Löst das dein Problem? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:08 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