0

いくつかのカスタム Enumerator-Set を作成しました。

例:

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

ここで、セットで定義されたすべてのアイテムでコンボボックスを埋めたいと思います。したがって、私の最初の考えは、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;

(別のアダプタを使用して TStringList を ComboBox にバインドしようとしましたが、うまくいきませんでした)。

ComboBox を埋めた後、LiveBindings を使用してプロパティ「SelectedValue」を、単に Status と呼ばれるオブジェクトの TStatus プロパティにバインドしました。

property Status:String read GetStatus write SetStatus;

ただし、3 つの問題があります。

  1. Status プロパティにデフォルト値を割り当てたにもかかわらず、オブジェクトをスクロールするとコンボボックスに値が表示されません。

  2. コンボボックス内のアイテムの量は次のとおりです。

     Amount of Items in Set + Amount of Objects
    

    したがって、2 つのオブジェクトがある場合、コンボボックスには 6 つのアイテムがあり、4 のままにしておく必要があります。

  3. コンボボックスから値を選択し、それをオブジェクトにポストしたい場合、それは私のセッター関数にアクセスしません。

この Live Bindings 全体は、私にとってはまだ新しいものですが、きちんと学びたいと思っています。

したがって、これらの問題を解決するのを手伝っていただければ幸いです。

お時間をいただきありがとうございます。

編集: 私の Delphi バージョンは 10.1 ベルリンで、VCL を使用しています。ターゲット プラットフォームは Windows のみです。

Edit2: https://www.dropbox.com/s/u7znetur723q6i2/DBApp.7z?dl=0 ここに私のプロジェクト ファイルがあります。

4

1 に答える 1

1

State-Pattern の実装など、多くのことを試しました。

プロパティは次のようになります。

property Status:String read ReadStatus write SetStatus;

各状態には、状態に関するリテラル情報を保持する定数文字列が含まれるようになりました。これを定数「Statusbez」と呼びました。これは、データベースに渡される情報です。

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

Status を設定するために、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;

実行時に State を設定するために、LiveBindings-Principle を破って Combobox の OnCloseUp-Event を使用する必要がありました。 .

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

コンポーネントのイベントに頼らなければならなかったことにあまり満足していませんが、仕事を成し遂げるものは何でもうまくいくと思います。

とにかく、データベース内の単語を安全に使用して状態を調べ、あちこちの数字や switch-case ステートメントの代わりに別のクラスの背後にロジックを置くことができるようになりました。

于 2016-12-27T22:33:39.277 に答える