Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#3

AW: TcxCheckComboBoxProperties und veränderliche Items

  Alt 2. Aug 2012, 11:23
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.
- 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);
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 2. Aug 2012 um 11:29 Uhr)
  Mit Zitat antworten Zitat