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

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

我创建了一些自定义枚举器集。

示例:

Type TStatus=(Unknown=0, Dead=1, Owned=2, Borrowed=3);

现在我想用我的集合中定义的所有项目填充一个组合框。 所以我首先想到的是使用 TypeInfo、GetEnumName 和 GetEnumValue 函数。

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;

(我尝试使用单独的适配器将 TStringList 绑定到 ComboBox,但这没有用)。

填充 ComboBox 后,我继续使用 LiveBindings 绑定 属性 "SelectedValue" 到我对象的 TStatus-属性,简称为 Status。

property Status:String read GetStatus write SetStatus;

虽然存在三个问题。

  1. 当我滚动对象时,组合框没有显示任何值,即使我为状态分配了默认值-属性。

  2. 组合框中的项目数量是:

     Amount of Items in Set + Amount of Objects
    

    所以如果我有 2 个对象,我的组合框中有 6 个项目,而它应该保持在 4

  3. 如果我 select 来自组合框的值并想 Post 它到我的对象,它不会访问我的 Setter-函数。

整个 Live Bindings 的东西对我来说仍然是新的,但我想正确地学习它。

所以如果你能帮我解决这些问题,我将不胜感激。

感谢您的宝贵时间。

编辑:我的 Delphi- 版本是 10.1 Berlin,我使用 VCL,目标平台只有 Windows。

编辑2: https://www.dropbox.com/s/u7znetur723q6i2/DBApp.7z?dl=0 这是我的项目文件。

我现在尝试了很多东西,包括状态模式的实现。

属性 现在看起来像这样:

property Status:String read ReadStatus write SetStatus;

每个状态现在都有一个常量字符串,它保存关于它是什么状态的文字信息,我称之为常量"Statusbez",这是现在传递到数据库的信息。

function THund.ReadStatus():String;
begin
  if fStatus<>nil then Result:=fStatus.Statusbez;
end;

为了设置状态,我访问了我的 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;

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;

为了在运行时设置状态,我不得不打破 LiveBindings-Principle 并使用 Combobox 的 OnCloseUp-Event,以下行获取 Combobox 中的 Text,解析我的 Enumeration-Type,获取 Enumvalue 和通过它分配一个状态。

Hund.Status:=CB_Hund_Status.Items[CB_Hund_Status.ItemIndex];

我不太高兴我不得不求助于组件的事件,但我想无论如何都能完成工作。

无论如何,现在我可以安全地使用我的数据库中的单词来检查状态并将我的逻辑放在单独的 类 后面,而不是到处都是数字和 switch-case 语句。