I have created a few custom Enumerator-Sets.
Example:
Type TStatus=(Unknown=0, Dead=1, Owned=2, Borrowed=3);
Now I want to fill a Combobox with all the Items defined in my Set. So my fist thought was to use the TypeInfo, GetEnumName and GetEnumValue-Functions.
i:=0;
while GetEnumValue(TypeInfo(TStatus),GetEnumName(TypeInfo(TStatus),i))<>-1 do
begin
status:=GetEnumName(TypeInfo(TStatus),i);
ComboBox.Items.Add(status);
inc(i);
end;
(I tried binding a TStringList to the ComboBox with a seperate Adapter but that didn't work).
After filling my ComboBox I went on to use LiveBindings to bind the property "SelectedValue" to the TStatus-property of my Object, which is simply called Status.
property Status:String read GetStatus write SetStatus;
there are three problems though.
The Combobox shows no Value when I scroll through my Objects even though I assigned a default value to the Status-property.
the Amount of Items in the combobox is:
Amount of Items in Set + Amount of Objects
So if I have 2 Objects I have 6 Items in my Combobox when it should remain at 4
If I select a Value from the combobox and want to Post it to my Object it doesnt access my Setter-Function.
This whole Live Bindings stuff is still new to me but I'd like to learn it properly.
So if you could help me solve these issues, it would be appreciated.
Thank you for your time.
Edit: My Delphi-Version is 10.1 Berlin and I use VCL, Target Platform is Windows only.
Edit2: https://www.dropbox.com/s/u7znetur723q6i2/DBApp.7z?dl=0 here are my project files.
I tried a lot of stuff now, including implementation of the State-Pattern.
the property looks now like this:
property Status:String read ReadStatus write SetStatus;
each state has now a constant String which holds the literal-information about what state it is, I called the constant "Statusbez", this is the information that gets passed on to the database now.
function THund.ReadStatus():String;
begin
if fStatus<>nil then Result:=fStatus.Statusbez;
end;
In order to set a Status I access my TStates-type, which is an enumeration type of all states I will eventually end up with.
procedure THund.SetStatus(value:string);
var
tempState:String;
i:Integer;
begin
tempState:=fStatus.Statusbez;
i:=GetEnumValue(TypeInfo(TStates),value);
fStatus:=ChangeStatus(i);
if fStatus.Statusbez<>tempState then fUpdated:=True;
end;
the changeStatus function simply decides which state to initialize.
function THund.ChangeStatus(value:Integer):TStatus;
begin
fStatus.Free();
case value of
Ord(Vorhanden):Result:=nil;
Ord(Verstorben):Result:=TDead.Create();
Ord(Schwanger):Result:=nil;
Ord(Reserviert):Result:=nil;
Ord(Laeufig):Result:=nil;
Ord(Verkauft):Result:=nil;
Ord(Gnadenbrot):Result:=nil;
else Result:=nil;
end;
end;
In order to set the State at runtime I had to break the LiveBindings-Principle and use the Combobox's OnCloseUp-Event, the following line takes the Text in the Combobox, parses over my Enumeration-Type, gets the Enumvalue and assigns a State through it.
Hund.Status:=CB_Hund_Status.Items[CB_Hund_Status.ItemIndex];
I am not very happy that I had to resort to the Events of the component but whatever gets the job done I suppose.
anyways, now I can safely use words in my database to examine the state and put my logic behind seperate classes instead of numbers and switch-case statements here and there.