delphi – 可以使用RTTI以编程方式更改属性写入方法以创建对象感知控件吗?

我有一个业务对象,我想更好地“连接”到我的UI.我已经看到了一些使对象具有数据感知能力的部分解决方案,但它们都涉及对业务对象的重大更改,包括额外的抽象层.

我一直在研究新版本Delphi中改进的RTTI,它看起来非常有趣和有用.我想知道我是否可以使用它以编程方式为所有属性注入新的写入方法.

这将起作用的方式是我的TEdit后代将在构建表单时给出对象属性的引用.然后,TEdit将在该属性的属性中插入对自身的引用(当然,在析构函数中删除自身或者给出另一个引用). TEdit还将确保该属性的write方法被替换为在调用原始write方法后通知TEdit更改的方法.

这可行吗?最重要的阻止是注入新的写入方法是不可能的,因此这个问题的标题.

派生属性也存在潜在问题,但应该可以找到解决方案.

最佳答案 在这篇名为“诱导大分裂”的
post中,
Cobus Kruger讨论了业务对象.

他煮的解决方案基本上符合您的要求:

>利用最近Delphi版本中引入的高级RTTI功能.
>将业务逻辑与表示逻辑分离.

任何PODO(Plain Old Delphi Object)都将作为业务对象!

魔术位于TObjectBinding类中,它将任何TWinControl与任何业务对象联系起来.

摘抄:

TObjectBinding = class
private
  fCtx: TRttiContext;
  fControlType: TRttiType;
  fObjType: TRttiType;

  fPropFieldMapping: TDictionary<TRttiProperty, TRttiField>; // Dictionary of object Properties & corresponding Fields

  fControl: TWinControl; // The control (normally form)
  fObj: TObject; // Object it represents.

  procedure CreateMappings; 

  function FindField(Prop: TRttiProperty; out Field: TRttiField): Boolean;
  function FieldClass(Field: TRttiField): TClass;

  // Modify these to change the rules about what should be matched.
  function IsValidField(Field: TRttiField): Boolean;
  function IsValidProp(Prop: TRttiProperty): Boolean;

  // Modify these to change the mappings of property type to VCL control class.
  procedure AssignField(Prop: TRttiProperty; Field: TRttiField);
  procedure AssignProp(Prop: TRttiProperty; Field: TRttiField);

  // Used from AssignField/AssignProp. Extend these to support a wider range of properties.
  function GetPropText(Prop: TRttiProperty): string;
  procedure SetPropText(Prop: TRttiProperty; const Text: string);
public
  constructor Create(Control: TWinControl; Obj: TObject);
  destructor Destroy; override;
  //
  procedure Load;
  procedure Save;
end;

我希望这对你来说是一个很好的起点.

点赞