Setting filter fails on freshly opened Objectdataset when user defined Fields are used

Issue #331 resolved
Rainer Wolff created an issue

If you use an Objectdataset and set user defined fields and the sort property immidiately on creation, the field
fProperties: IList<TRttiProperty>;
is not initialized and therefore the sort property is not set.

Solution: Add Check and initialization in procedure InternalSetSort.

Code demonstrating the problem:

type
  TPerson = class
  private
    FVorname: string;
    FNachname: String;
  published
    constructor Create (aVorname, aNachname:string);
    property Vorname: string read FVorname write FVorname;
    property Nachname: String read FNachname write FNachname;
  end;

  TForm12 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form12: TForm12;

implementation

{$R *.dfm}

procedure TForm12.FormCreate(Sender: TObject);
var
  Objectdataset: TObjectDataset;
  LStrField: TStringField;
  LIntField: TIntegerField;
  personlist: IList<TPerson>;
begin
  personlist:=TCollections.CreateList<TPerson>;
  personlist.Add(TPerson.Create('a','wolf'));
  personlist.Add(TPerson.Create('a','meier'));

  Objectdataset:= TObjectDataset.Create(self);
  Objectdataset.DataList:=personlist as IObjectlist;

  LStrField := TWideStringField.Create(Objectdataset);
  LStrField.FieldName := 'Vorname';
  LStrField.DataSet := Objectdataset;

  LStrField := TWideStringField.Create(Objectdataset);
  LStrField.FieldName := 'Nachname';
  LStrField.DataSet := Objectdataset;

  Objectdataset.Open;
  Objectdataset.Sort:='Nachname';

  if not Objectdataset.Sorted then
    raise Exception.Create('Not sorted');  // Here Dataset is not sorted

end;

{ TPerson }

constructor TPerson.Create(aVorname, aNachname: string);
begin
  FVorname:=aVorname;
  FNachname:=aNachname;
end;

My solution proposal:

procedure TObjectDataSet.InternalSetSort(const value: string; index: Integer);
var
  pos: Integer;
  ownership: ICollectionOwnership;
  ownsObjects: Boolean;
  changed: Boolean;
begin
  if IsEmpty then
    Exit;

  DoBeforeSort;

  if not fProperties.Any then  // <--- check if properties exist
    InitRttiPropertiesFromItemType(fItemTypeInfo);  <---  otherwise initialize 

  changed := value <> fSort;
  fIndexFields := CreateIndexList(value);
  fSorted := Length(fIndexFields) > 0;
  fSort := value;

Comments (2)

  1. Log in to comment