在另一个过程中设置对象的属性

时间:2013-06-18 18:57:00

标签: delphi checkbox boolean

我有一个具有一些属性的对象:

Obj.Big
Obj.Rotate
Obj.Paint
Obj.Lines

等。它们都是布尔类型属性。

在我的主要程序中,我称之为另一个程序:

procedure TMainForm.Create(Sender:TObject);
begin
     SetParameter(BigCheckBox, Obj.Big);
     SetParameter(RotateCheckBox, Obj.Rotate);
     SetParameter(PaintCheckBox, Obj.Paint);
     SetParameter(LinesCheckBox, Obj.Lines);
end;

SetParameter程序如下:

procedure TMainForm.SetParameter(ACheckBox : TCheckBox; ABoolOption : Boolean);
begin
    if(ACheckBox.Checked) and (ACheckBox.Enabled) then begin
      ABoolOption := true;
    end
    else if(not ACheckBox.Checked) and (ACheckBox.Enabled) then begin
      ABoolOption := false;
    end;
end;

它接受checkbox对象和传递对象的布尔属性的属性为ABoolOption。我不能简单地做LinesCheckBox.Checked := Obj.Lines因为我需要在填充复选框时执行“不执行任何操作”(它们都是三态)。当我运行它时,这些对象的参数都没有改变。这是为什么?

2 个答案:

答案 0 :(得分:5)

你没有通过财产。您正在传递该属性的。我的SetParameter正在接收ACheckBox, TrueACheckBox, False,因此您无需更改。更好的方法是将SetParameter过程更改为函数:

function TMainForm.SetBooleanValue(const ACheckBox: TCheckBox): Boolean;
begin
  Result := (ACheckBox.Checked) and (ACheckBox.Enabled);
end;

然后使用它:

Obj.Big := SetBooleanValue(BigCheckbox);
Obj.Rotate := SetBooleanValue(RotateCheckBox);
Obj.Paint := SetBooleanValue(PaintCheckBox);
Obj.Lines := SetBooleanValue(LinesCheckBox);

如果您需要允许第三个选项,则应在执行SetBooleanValue的呼叫之前先检查它:

if not ThirdCondition then
  Obj.Big := SetBooleanValue(BigCheckBox);

答案 1 :(得分:1)

您的程序没有按照您的想法执行。您 NOT 传递属性本身,而是传递属性的 CURRENT VALUE 。如果您想要实际更新属性的值,您需要执行Ken建议,或者使用RTTI,例如:

uses
  ..., TypInfo;

procedure TMainForm.Create(Sender:TObject);
begin
  SetBooleanParameter(BigCheckBox, Obj, 'Big');
  SetBooleanParameter(RotateCheckBox, Obj, 'Rotate');
  SetBooleanParameter(PaintCheckBox, Obj, 'Paint');
  SetBooleanParameter(LinesCheckBox, Obj, 'Lines');
end;

procedure TMainForm.SetBooleanParameter(ACheckBox : TCheckBox; Obj: TObject; const PropName: String);
begin
  if ACheckBox.Enabled then begin
    // NOTE: this only works if the properties are declared as 'published'
    SetOrdProp(Obj, PropName, Ord(ACheckBox.Checked));
  end;
end;

或者,如果您使用的是D2010 +:

uses
  ..., Rtti;

procedure TMainForm.Create(Sender:TObject);
begin
  SetBooleanParameter(BigCheckBox, Obj, 'Big');
  SetBooleanParameter(RotateCheckBox, Obj, 'Rotate');
  SetBooleanParameter(PaintCheckBox, Obj, 'Paint');
  SetBooleanParameter(LinesCheckBox, Obj, 'Lines');
end;

procedure TMainForm.SetBooleanParameter(ACheckBox : TCheckBox; Obj: TObject; const PropName: String);
var
  Ctx: TRttiContext;
begin
  if ACheckBox.Enabled then
  begin
    // NOTE: this approach does not need the properties to be declared as 'published'
    Ctx.GetType(Obj.ClassType).GetProperty(PropName).SetValue(Obj, TValue.From<Boolean>(ACheckBox.Checked));
  end;
end;