Delphi Livebinding对象和组合框或单选按钮

Delphi Livebinding对象和组合框或单选按钮,delphi,livebindings,tcombobox,tobject,Delphi,Livebindings,Tcombobox,Tobject,我为业务逻辑定义了后续单元 unit Models.Person; interface Type TPersonGender = (pgUndefined, pgMale, pgFemale, pgNotApplicable); TSexOfPerson = class(TPersistent) private FGender : TPersonGender; protected function GetDescription : string; f

我为业务逻辑定义了后续单元

unit Models.Person;

interface

Type
  TPersonGender = (pgUndefined, pgMale, pgFemale, pgNotApplicable);

  TSexOfPerson = class(TPersistent)
  private
    FGender : TPersonGender;
  protected
    function GetDescription : string;
    function GetCode : string;
    function GetIndex : integer;
  public
    constructor Create; overload;
    constructor Create(const aValue : TGenderPerson); overload;
    procedure Assign(Source: TPersistent); override;
    property Gender : TGenderPerson read FGender write FGender;
    property Description : string read GetDescription;
    property Code : string read GetCode;
    property Index : integer read GetIndex;
  end;

  TPerson = class(TPersistent)
  private
    FSex : TSexOfPerson;
    FName : string;
    FSurName : string;
    FAddress : string;
  protected
    function GetSex : TPersonGender;
    procedure SetSex(aGender : TPersonGender);
  public
    constructor Create; overload;
    constructor Create(const aValue : TPerson); overload;
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
    property Name : string read FName write FName;
    property SurName : string read FSurName write FSurName;
    property Address : string read FAddress write FAddress;
    property Sex : TPersonGender read GetSex write SetSex
  end;

implementation

{ TSexOfPerson }

constructor TSexOfPerson.Create;
begin
  inherited Create;
  FGender := pgUndefined;
end;

constructor TSexOfPerson.Create(const aValue : TPersonGender);
begin
  inherited Create;
  FGender := aValue
end;

procedure TSexOfPerson.Assign(Source: TPersistent);
begin
  if Source is TSexOfPerson then
    FGender := TSexOfPerson(Source).Gender
  else
    inherited Assign(Source)
end;

function TSexOfPerson.GetDescription;
begin
  case FGender of
    pgUndefined : Result := '<Undefined>';
    pgMale : Result := 'Male';
    pgFemale : Result := 'Female';
    pgNotApplicable : Result := '<Not applicable>';
  end
end;

function TSexOfPerson.GetIndex;
begin
  Result := Ord(FGender)
end;

function TSexOfPerson.GetCodice;
begin
  case FGender of
    pgUndefined : Result := '';
    pgMale : Result := 'M';
    pgFemale : Result := 'F';
    pgNotApplicable : Result := 'N'
  end
end;

{ TPerson }

constructor TPerson.Create;
begin
  inherited Create;
  FSex := TSexOfPerson.Create(pgUndefined)
end;

constructor TPerson.Create(const aValue : TPerson);
begin
  inherited Create;
  FSex := TSexOfPerson.Create(aValue)
end;

destructor TPerson.Destroy;
begin
  FSex.Free;
  inherited Destroy
end;

procedure TPerson.Assign(Source: TPersistent);
begin
  if Source is TPerson then
  begin
    FName := TPerson(Source).Name;
    FSurName := TPerson(Source).SurName;
    FAddress := TPerson(Source).Address;
    FSex.Gender := TPerson(Source).Sex;
  end
  else
    inherited Assign(Source)
end;

function GetSex : TPersonGender;
begin
  Result := FSex.Gender
end;

procedure SetSex(aGender : TPersonGender);
begin
  if FSex.Gender <> aGender then
    FSex.Gender := aGender
end;

end.
unitmodels.Person;
接口
类型
TPersonGender=(pgUndefined,pgMale,pgFemale,pgnotapplicate);
TSexOfPerson=class(TPersistent)
私有的
FGender:TPersonGender;
受保护的
函数GetDescription:字符串;
函数GetCode:string;
函数GetIndex:integer;
公众的
构造函数创建;超载;
构造函数创建(const aValue:TGenderPerson);超载;
程序分配(来源:TPersistent);推翻
属性性别:TGenderPerson read FGender write FGender;
属性描述:字符串读取GetDescription;
属性代码:字符串读取GetCode;
属性索引:整数读取GetIndex;
结束;
TPerson=类(TPersistent)
私有的
FSex:TSexOfPerson;
FName:字符串;
FSurName:字符串;
时尚服饰:细绳;
受保护的
函数GetSex:TPersonGender;
程序SetSex(代理商:TPersonGender);
公众的
构造函数创建;超载;
构造函数创建(const aValue:TPerson);超载;
毁灭者毁灭;推翻
程序分配(来源:TPersistent);推翻
属性名称:字符串读取FName写入FName;
属性姓氏:字符串读取FSurName写入FSurName;
属性地址:字符串读取FAddress写入FAddress;
属性性别:TPersonGender read GetSex write SetSex
结束;
实施
{TSexOfPerson}
构造函数TSexOfPerson.Create;
开始
继承创造;
FGender:=pgUndefined;
结束;
构造函数TSexOfPerson.Create(const aValue:TPersonGender);
开始
继承创造;
FGender:=aValue
结束;
程序TSexOfPerson.Assign(来源:TPersistent);
开始
如果来源是TSexOfPerson,那么
FGender:=TSexOfPerson(来源)。性别
其他的
继承分配(源)
结束;
函数TSexOfPerson.GetDescription;
开始
案例F
pgUndefined:结果:='';
pgMale:结果:='男';
pgFemale:结果:='Female';
pgNotApplicable:结果:='';
结束
结束;
函数TSexOfPerson.GetIndex;
开始
结果:=Ord(FGender)
结束;
函数TSexOfPerson.GetCodice;
开始
案例F
pgUndefined:结果:='';
pgMale:结果:='M';
pgFemale:结果:='F';
pgNotApplicable:结果:='N'
结束
结束;
{TPerson}
构造函数TPerson.Create;
开始
继承创造;
FSex:=TSexOfPerson.Create(pgUndefined)
结束;
构造函数TPerson.Create(const aValue:TPerson);
开始
继承创造;
FSex:=TSexOfPerson.Create(aValue)
结束;
毁灭者,毁灭者;
开始
免费;
继承性破坏
结束;
程序TPerson.Assign(来源:TPersistent);
开始
如果来源是TPerson,那么
开始
FName:=TPerson(Source).Name;
FSurName:=TPerson(来源)。姓氏;
FAddress:=TPerson(源)。地址;
性别:=TPerson(来源)。性别;
结束
其他的
继承分配(源)
结束;
函数GetSex:TPersonGender;
开始
结果:=FSex.性别
结束;
程序SetSex(代理商:TPersonGender);
开始
如果是FSex.性别代理,则
性别:=aGender
结束;
结束。
现在,我将设计一个用于编辑TPerson的表单,用三个TEdit和一个TCombobox来选择性别


如何为Tcombox使用双向livebinding?

鉴于使用Delphi在复杂类和控件之间进行livebinding并不容易,为了简化,我认为应该如下更改TPerson类:

TPerson = class(TPersistent)
  private
    FSex : TSexOfPerson;
    FName : string;
    FSurName : string;
    FAddress : string;
  protected
    function GetSex : TPersonGender;
    procedure SetSex(aGender : TPersonGender);
  public
    constructor Create; overload;
    constructor Create(const aValue : TPerson); overload;
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
    property Name : string read FName write FName;
    property SurName : string read FSurName write FSurName;
    property Address : string read FAddress write FAddress;
    property Sex : integer read GetSex write SetSex
  end;

implementation

...

function TPerson.GetSex : integer;
begin
  Result := FSex.Index
end;

procedure TPerson.SetSex (aValue : integer);
begin
  if FSex.Integer <> aValue then
    case aValue of
    0 : FSex.MtsSesso := pgUndefined;
    1 : FSex.MtsSesso := pgMale;
    2 : FSex.MtsSesso := pgFemale;
    3 : FSex.MtsSesso := pgNotApplicable;
    end;
end;

procedure TPerson.Assign(Source: TPersistent);
begin
  if Source is TPerson then
  begin
    FName := TPerson(Source).Name;
    FSurName := TPerson(Source).SurName;
    FAddress := TPerson(Source).Address;
    case TPerson(Source).Sex of
    0 : FSex.MtsSesso := pgUndefined;
    1 : FSex.MtsSesso := pgMale;
    2 : FSex.MtsSesso := pgFemale;
    3 : FSex.MtsSesso := pgNotApplicable;
    end;
  end
  else
    inherited Assign(Source)
end;
...
就这些


我希望该解决方案足够强大,并且更容易重申。

如果您使用TComboBox而不是TRadioButtons,我们将以这种方式继续。 我更喜欢为TSexOfPerson类创建适配器:

type

  TSexOfPersonsAdapter = class(TListBindSourceAdapter<TSexOfPerson>)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  procedure Register;

...

constructor TSexOfPersonsAdapter.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  //load Sex Persons list
  SetList(LoadSexOfPerson)
end;

procedure Register;
begin
  RegisterComponents('CustomAdapters', [TSexOfPersonsAdapter]);
end;

function LoadSexOfperson: TList<TSexOfPerson>;
begin
  Result := TObjectList<TSexOfPerson>.Create;

  Result.Add(TSexOfPerson.Create(pgUndefined));
  Result.Add(TSexOfPerson.Create(pgMale));
  Result.Add(TSexOfPerson.Create(pgFemale));
  Result.Add(TSexOfPerson.Create(pgNotApplicable));
end;
在ComboBox1上,按如下方式设置OnChange

procedure TForm1.ComboBox1Change(Sender: TObject);
var
  aValue : TValue;
begin
  aValue := LinkFillControlToField1.BindList.GetSelectedValue;
  case aValue.AsInteger of
  Ord(pgUndefined)     : CurrentPerson.Sex := Ord(pgUndefined);
  Ord(pgMale)          : CurrentPerson.Sex := Ord(pgMale);
  Ord(pgFemale)        : CurrentPerson.Sex := Ord(pgFemale);
  Ord(pgNotApplicable) : CurrentPerson.Sex := Ord(pgNotApplicable);
  end
end;
就这些

procedure TForm1.RadioButton1Click(Sender: TObject);
begin
   if not TRadioButton(Sender).IsChecked then
     CurrentPerson.Sex := Ord(pgUndefined)
end;

procedure TForm1.RadioButton2Click(Sender: TObject);
begin
   if not TRadioButton(Sender).IsChecked then
     CurrentPerson.Sex := Ord(pgMale)
end;

procedure TForm1.RadioButton3Click(Sender: TObject);
begin
   if not TRadioButton(Sender).IsChecked then
     CurrentPerson.Sex := Ord(pgFemale)
end;

procedure TForm1.RadioButton4Click(Sender: TObject);
begin
   if not TRadioButton(Sender).IsChecked then
     CurrentPerson.Sex := Ord(pgNotApplicable)
end;
type

  TSexOfPersonsAdapter = class(TListBindSourceAdapter<TSexOfPerson>)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  procedure Register;

...

constructor TSexOfPersonsAdapter.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  //load Sex Persons list
  SetList(LoadSexOfPerson)
end;

procedure Register;
begin
  RegisterComponents('CustomAdapters', [TSexOfPersonsAdapter]);
end;

function LoadSexOfperson: TList<TSexOfPerson>;
begin
  Result := TObjectList<TSexOfPerson>.Create;

  Result.Add(TSexOfPerson.Create(pgUndefined));
  Result.Add(TSexOfPerson.Create(pgMale));
  Result.Add(TSexOfPerson.Create(pgFemale));
  Result.Add(TSexOfPerson.Create(pgNotApplicable));
end;
SexOfPersonABS.Adapter = SexOfPersonsAdapter1;
PersonABS.Adapter = PersonsAdapter1;
PersonABS.OnCreateAdapter = PersonABSCreateAdapter;

procedure TForm1.PersonABSCreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter);
begin
  ABindSourceAdapter := TObjectBindSourceAdapter<TPerson>.Create(PersonABS, CurrentPerson, False);
  ABindSourceAdapter.AutoPost := True;
end;
LinkFillControlToField1.Control    = ComboBox1;
LinkFillControlToField1.DataSource = PersonABS;
LinkFillControlToField1.FieldName  = 'Sex';

LinkFillControlToField1.FillDataSource = SexOfPersonABS;
LinkFillControlToField1.FillDisplayFieldName = 'Description';
LinkFillControlToField1.FillValueFieldName = 'Index';
procedure TForm1.ComboBox1Change(Sender: TObject);
var
  aValue : TValue;
begin
  aValue := LinkFillControlToField1.BindList.GetSelectedValue;
  case aValue.AsInteger of
  Ord(pgUndefined)     : CurrentPerson.Sex := Ord(pgUndefined);
  Ord(pgMale)          : CurrentPerson.Sex := Ord(pgMale);
  Ord(pgFemale)        : CurrentPerson.Sex := Ord(pgFemale);
  Ord(pgNotApplicable) : CurrentPerson.Sex := Ord(pgNotApplicable);
  end
end;