The previous post introduced a utility method called FillList and showed how to call it using BindScopeDB1 as the source component. TBindScopeDB allows TBindList to work with a TDataSet.
This post shows a version of FillList which can work with enumerable objects such at TStrings or TList<> (an object is enumerable if it implements GetEnumerator). TBindScope is used instead of TBindScopeDB.
Here is a FillList method which can populate a list control from an enumerable object:
procedure FillList(AControl: TComponent; const AControlExpression: string; AEnumerableObject: TObject; const ASourceExpression: string); overload; var LBindList: TBindList; LBindScope: TBindScope; I: Integer; begin LBindScope := TBindScope.Create(nil); LBindList := TBindList.Create(nil); try // Turn off auto properties. LBindList.AutoFill := False; LBindList.AutoActivate := False; LBindList.ControlComponent := AControl; // Scope references the enumerable object LBindScope.DataObject := AEnumerableObject; LBindList.SourceComponent := LBindScope; with LBindList.FormatExpressions.AddExpression do begin SourceExpression := ASourceExpression; ControlExpression := AControlExpression; end; LBindList.FillList; finally LBindList.Free; LBindScope.Free; end; end;
Call FillList as follows to populate a ListBox or ComboBox with the values from a TStrings:
procedure ListStrings(AListControl: TControl); var LStrings: TStrings; begin LStrings := TStringList.Create; try LStrings.DelimitedText := 'one,two,three,four,five,six'; FillList(AListControl, 'Text', LStrings, 'Current'); finally LStrings.Free; end; end;
‘Text’ references the list item text. ’Current’ references the property Current of TStringsEnumerator.
Instead of TStrings we can also use a generic collection of string:
procedure ListStrings(AListControl: TControl); var LStrings: TList<string>; begin LStrings := TList<string>.Create; try LStrings.AddRange( TArray<string>.Create('one','two','three')); FillList(AListControl, 'Text', LStrings, 'Current'); finally LStrings.Free; end; end;
And also a generic collection of object:
type TSampleObject = class private FStringProp: string; FIntegerProp: Integer; public constructor Create(AIntegerProp: Integer); property StringProp: string read FStringProp; property IntegerProp: Integer read FIntegerProp; end; procedure ListSampleObjects(AListControl: TControl); var LList: TList<TSampleObject>; I: Integer; begin LList := TObjectList<TSampleObject>.Create; // Owns objects try for I := 1 to 10 do LList.Add(TSampleObject.Create(I)); FillList(AListControl, 'Text', LList, 'ToStr(Current.IntegerProp) + ": " + Current.StringProp'); finally LList.Free; end; end;
As mentioned in the previous post, you will need to use FMX.Binding.Editors. For VCL projects, use VCL.Binding.Editors.
A sample project using FillList is available on sourceforge:
{ 1 } Comments
Hi Jim !
First of all, thanks for live bindings. I didnt use it yet, but I notice that a great feature.
But, I think that most interesting you to do some examples closer reality developers, like binding Business Objects persisting it with DBWare and not DBware components.
make some example like a simple class TPerson or TCustomer persisting in some database like Firebird.
Try do it ! I think people will like it !
Best regards
Post a Comment