1

我们有一个成员表,其中包含一个字段(作为整数),用于通过他的 id 定义“成员身份”。例如:0 表示不活跃,1 表示活跃,2 表示终生,3 表示退休,4 表示杰出成就,等等,

我们使用 LiveBindings 将 StringGrid 附加到 Members 表。因此,在网格中,我们看到状态的 id 号(1 或 2 或等)。但我们希望看到该状态的“标签”(例如:LifeTime)而不是他的 ID。

作为信息,“状态标签”不能存储在查找表中,因为它必须翻译成不同的语言。

我创建了一个对象,其中包含ObjMemberStatus:TObjectList<TMemberStatus>;
使用TAdapterBindSource 保存成员资格标签的状态。

我能够使用TDataGenerator将此信息分配给 ComboBox 。我认为这是在这种情况下使用 ComboBox 的方法,这对此非常有效。

我的问题是:如何将 AdapterBindSource 中包含的标签显示到网格的列?

我已经执行了一些搜索,但没有看到如何直接使用 LiveBindings 进行搜索。也许我错过了一些东西。

我还在帮助中看到我们可以添加该方法:Lookup(scope lookup, key fields, key values, result fields)到 CustumFormat 属性。但是没有示例显示如何使用该 CustumFormat 方法。我在网上搜索过,似乎没有记录。

子问题,有没有办法绕过或挂钩一些代码到 LiveBindings 数据分配给组件进程?

4

2 回答 2

0

正如我在评论中所说,我已经使用与包含代码和本地化描述的 memtable 链接的查找字段来完成此操作。

但最近我使用了另一种方法,在你的情况下可能更容易实现。我将代码字段的 GetText 和 SetText 事件与以下内容联系起来:

Procedure TSomeLookupFieldHandler.LookupFieldHandleGetText(Sender: TField; Var Text: String; DisplayText: Boolean);
Var
  v: Variant;
Begin
  Text := '';
  If (DataSet <> Nil) And Not Sender.IsNull Then Begin
    DataSet.Active := True;
    v := DataSet.Lookup(KeyFieldName, Sender.Value, ResultFieldName);
    If Not VarIsNull(v) And Not VarIsEmpty(v) Then
      Text := v;
  End;
End;

Procedure TSomeLookupFieldHandler.LookupFieldHandleSetText(Sender: TField; Const Text: String);
Var
  v: Variant;
Begin
  If Text.IsEmpty Or (DataSet = Nil) Then
    Sender.Clear
  Else Begin
    DataSet.Active := True;
    v := DataSet.Lookup(ResultFieldName, Text, KeyFieldName);
    If Not VarIsNull(v) And Not VarIsEmpty(v) Then
      Sender.Value := v
    Else
      Sender.Clear;
  End;
End;

TSomeLookupFieldHandler 对象有一个对 DataSet 的引用,它可以用来进行查找(我有很多像这样工作的字段)。每次我需要的查找时,我都会实例化一个这样的对象。

如果您希望该字段为只读,我不确定是否需要 SetText 事件处理程序。我的不是。

本地化的描述仍然需要在某些数据集中,例如 TFDMemTable……但您可以轻松地修改它以在 TStringList 或 TObjectList 或其他容器上进行查找。

要使用它,您需要实例化此类的一个对象,然后连接一个或多个字段:

lfh := TSomeLookupFieldHandler.Create(<Some parameters to setup the lookup dataset>);

SomeField.GetText:=lfh.LookupFieldHandleGetText;
SomeField.SetText:=lfh.LookupFieldHandleSetText;

SomeDataSet.FieldByName('code').GetText:=lfh.LookupFieldHandleGetText;
SomeDataSet.FieldByName('code').SetText:=lfh.LookupFieldHandleSetText;

如果您有许多要连接的字段,那么在 TSomeLookupFieldHandler 上添加一个新方法会更容易,该方法采用 TField 参数并进行设置。

于 2017-10-30T08:48:29.867 回答
0

你似乎在制造恶劣的天气。

我很欣赏翻译的复杂性,但最直接的做法就是应用 KISS 原则,并在数据集中添加一个计算字段,该字段提供成员身份的文本表示。

要处理翻译,最简洁的方法当然是为不同语言创建一个单独的成员状态文本表,并选择在运行时使用的语言。如果您不想为此烦恼,只需使用Valuesa 的属性TStringList在网格 DataSet 的 OnCalcFields 事件中查找翻译。

更新 说您可以将计算字段添加到 FDQuery 但不能添加到 FDMemtable 是不正确的。以下代码工作正常:

procedure TForm1.FDMemTable1CalcFields(DataSet: TDataSet);
begin
  DataSet.FieldByName('Description').AsString := IntToStr(DataSet.FieldByName('ID').AsInteger);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  F : TField;
begin
  F := TIntegerField.Create(Self);
  F.FieldName := 'ID';
  F.FieldKind := fkData;
  F.DataSet := FDMemTable1;

  F := TStringField.Create(Self);
  F.Size := 80;
  F.FieldName := 'Description';
  F.FieldKind := fkInternalCalc;
  F.DataSet := FDMemTable1;

  FDMemTable1.CreateDataSet;
  FDMemTable1.InsertRecord([1]);
  FDMemTable1.InsertRecord([2]);
end;

并在实时绑定的 StringGrid 中正确显示 ID 和描述这两个列。

于 2017-10-29T19:38:20.740 回答