我有一个具有一些属性的对象:
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
因为我需要在填充复选框时执行“不执行任何操作”(它们都是三态)。当我运行它时,这些对象的参数都没有改变。这是为什么?
答案 0 :(得分:5)
你没有通过财产。您正在传递该属性的值。我的SetParameter
正在接收ACheckBox, True
或ACheckBox, 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;