简体   繁体   English

Delphi-如何将枚举器类型的项目绑定到ComboBox并将所选项目绑定到对象

[英]Delphi - How to bind Items of an Enumerator-Type to a ComboBox and Bind Selected Item to An Object

I have created a few custom Enumerator-Sets. 我创建了一些自定义的Enumerator-Set。

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. 所以我的第一个想法是使用TypeInfo,GetEnumName和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). (我尝试使用单独的适配器将TStringList绑定到ComboBox,但这没有用)。

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. 填充完ComboBox之后,我继续使用LiveBindings将“ SelectedValue”属性绑定到我的Object的TStatus属性,简称为Status。

property Status:String read GetStatus write SetStatus;

there are three problems though. 但是有三个问题。

  1. The Combobox shows no Value when I scroll through my Objects even though I assigned a default value to the Status-property. 即使我为状态属性分配了默认值,当我滚动浏览对象时,组合框也没有显示任何值。

  2. 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 因此,如果我有2个对象,则我的组合框中有6个项目,而该项目应保持为4个项目

  3. 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. 整个Live Bindings内容对我来说仍然是新手,但我想正确学习。

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. 编辑:我的Delphi版本是10.1柏林,并且我使用VCL,目标平台是仅Windows。

Edit2: https://www.dropbox.com/s/u7znetur723q6i2/DBApp.7z?dl=0 here are my project files. Edit2: https ://www.dropbox.com/s/u7znetur723q6i2/DBApp.7z ? dl =0这是我的项目文件。

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. 每个状态现在都有一个常量String,该字符串保存有关状态的字面信息,我称之为常量“ Statusbez”,这是现在传递给数据库的信息。

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. 为了设置状态,我访问我的TStates类型,这是我最终将使用的所有状态的枚举类型。

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. changeStatus函数仅决定要初始化的状态。

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. 为了在运行时设置状态,我不得不打破LiveBindings原理并使用Combobox的OnCloseUp-Event,以下行将Combobox中的Text提取出来,解析我的Enumeration-Type,获取Enumvalue并通过它分配状态。

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. 无论如何,现在我可以安全地使用数据库中的单词来检查状态并将我的逻辑放在单独的类后面,而不是在这里和那里使用数字和大小写转换语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM