- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对如何从具有 TPersistent 字段的 TComponent 中写出属性感到非常困惑。例如我有:
TChildObj = class( TPersistent )
PRIVATE
FVisible: boolean;
FColor: TColor;
PUBLIC
PUBLISHED
property Visible : boolean
read FVisible
write FVisible;
property Color : TColor
read FColor
write FColor;
end;
TTest = class( TComponent )
constructor Create( AOwner : TComponent ); override;
destructor Destroy; override;
private
FChildObj : TChildObj;
FOne: integer;
published
property One : integer
read FOne
write FOne;
property ChildObj : TChildObj
read FChildObj;
end;
procedure TForm1.Button5Click(Sender: TObject);
var
MS : TMemoryStream;
SS : TStringStream;
Test : TTest;
begin
Test := TTest.Create( Self );
MS := TMemoryStream.Create;
SS := TStringStream.Create;
try
MS.WriteComponent( Test );
MS.Position := 0;
ObjectBinaryToText( MS, SS );
SS.SaveToFile( 'c:\scratch\test.txt' );
finally
MS.Free;
SS.Free;
end;
end;
object TTest
One = 0
end
if (PropInfo^.GetProc <> nil) and
((PropInfo^.SetProc <> nil) or
((PropInfo^.PropType^.Kind = tkClass) and
(TObject(GetOrdProp(Instance, PropInfo)) is TComponent) and
(csSubComponent in TComponent(GetOrdProp(Instance, PropInfo)).ComponentStyle))) then
最佳答案
当 RTL 决定是否需要流式传输 TPersistent
时,更仔细地查看需求列表。属性(property):
if (PropInfo^.GetProc <> nil) and
((PropInfo^.SetProc <> nil) or
((PropInfo^.PropType^.Kind = tkClass) and
(TObject(GetOrdProp(Instance, PropInfo)) is TComponent) and
(csSubComponent in TComponent(GetOrdProp(Instance, PropInfo)).ComponentStyle))) then
ChildObj
属性是只读属性,所以它不满足
PropInfo^.SetProc <> nil
要求,它不是
TComponent
-派生的子组件,所以它不满足是
is TComponent
和
csSubComponent
要求。这就是 DFM 中缺少您的属性(property)的原因。
ChildObj
属性是读/写而不是只读的(不要使用
TComponent
除非你必须这样做,在这种情况下你不需要这样做)。
TTest
中的析构函数释放
TChildObj
目的。为了更好的衡量,你应该给
TChildObj
一个
OnChange
事件
TTest
可以分配一个处理程序,因此它可以对
TChildObj
的更改使用react子属性。
type
TChildObj = class(TPersistent)
private
FVisible : Boolean;
FColor : TColor;
FOnChange : TNotifyEvent;
procedure Changed;
procedure SetVisible(Value : Boolean);
procedure SetColor(Value : TColor);
public
procedure Assign(Source : TPersistent); override;
property OnChange : TNotifyEvent read FOnChange write FOnChange;
published
property Visible : Boolean read FVisible write SetVisible;
property Color : TColor read FColor write SetColor;
end;
TTest = class(TComponent)
private
FChildObj : TChildObj;
FOne : integer;
procedure ChildObjChanged(Sender : TObject);
procedure SetChildObj(Value : TChildObj);
protected
procedure Loaded; override;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
published
property One : integer read FOne write FOne;
property ChildObj : TChildObj read FChildObj write SetChildObj;
end;
procedure TChildObj.Assign(Source: TPersistent);
begin
if Source is TChildObj then
begin
FVisible := TChildObj(Source).Visible;
FColor := TChildObj(Source).Color;
Changed;
end else
inherited;
end;
procedure TChildObj.Changed;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TChildObj.SetVisible(Value : Boolean);
begin
if FVisible <> Value then
begin
FVisible := Value;
Changed;
end;
end;
procedure TChildObj.SetColor(Value : TColor);
begin
if FColor <> Value then
begin
FColor := Value;
Changed;
end;
end;
constructor TTest.Create(AOwner : TComponent);
begin
inherited;
FChildObj := TChildObj.Create;
FChildObj.OnChange := ChildObjChanged;
end;
destructor TTest.Destroy;
begin
FChildObj.Free;
inherited;
end;
procedure TTest.ChildObjChanged(Sender : TObject);
begin
if csLoading in ComponentState then Exit;
// use ChildObj values as needed...
end;
procedure TTest.Loaded;
begin
inherited;
ChildObjChanged(nil);
end;
procedure TTest.SetChildObj(Value : TChildObj);
begin
if FChildObj <> Value then
FChildObj.Assign(Value);
end;
TComponent
方法,然后试试这个:
type
TChildObj = class(TComponent)
private
FVisible : Boolean;
FColor : TColor;
FOnChange : TNotifyEvent;
procedure Changed;
procedure SetVisible(Value : Boolean);
procedure SetColor(Value : TColor);
public
procedure Assign(Source : TPersistent); override;
property OnChange : TNotifyEvent read FOnChange write FOnChange;
published
property Visible : Boolean read FVisible write SetVisible;
property Color : TColor read FColor write SetColor;
end;
TTest = class(TComponent)
private
FChildObj : TChildObj;
FOne : integer;
procedure ChildObjChanged(Sender : TObject);
procedure SetChildObj(Value : TChildObj);
protected
procedure Loaded; override;
public
constructor Create(AOwner : TComponent); override;
published
property One : integer read FOne write FOne;
property ChildObj : TChildObj read FChildObj write SetChildObj;
end;
procedure TChildObj.Assign(Source: TPersistent);
begin
if Source is TChildObj then
begin
FVisible := TChildObj(Source).Visible;
FColor := TChildObj(Source).Color;
Changed;
end else
inherited;
end;
procedure TChildObj.Changed;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TChildObj.SetVisible(Value : Boolean);
begin
if FVisible <> Value then
begin
FVisible := Value;
Changed;
end;
end;
procedure TChildObj.SetColor(Value : TColor);
begin
if FColor <> Value then
begin
FColor := Value;
Changed;
end;
end;
constructor TTest.Create(AOwner : TComponent);
begin
inherited;
FChildObj := TChildObj.Create(Self);
FChildObj.SetSubComponent(True);
FChildObj.OnChange := ChildObjChanged;
end;
procedure TTest.ChildObjChanged(Sender : TObject);
begin
if csLoading in ComponentState then Exit;
// use ChildObj values as needed...
end;
procedure TTest.Loaded;
begin
inherited;
ChildObjChanged(nil);
end;
procedure TTest.SetChildObj(Value : TChildObj);
begin
if FChildObj <> Value then
FChildObj.Assign(Value);
end;
关于delphi - 我可以使用默认的 WriteComponent 操作将 Delphi TPersistent 序列化为 TComponent 的字段吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14763635/
我需要一个基于 TPersistent 的类(因此它存储 RTTI)并包括默认接口(interface)处理(QueryInterface、_AddRef、_Release)……我要查找的类名是什么?
我们使用SQL Direct Delphi XE2 6.4版本(Win7,64位,但我们只做32位开发)。 我正在制作一个新的测试应用程序并发现以下内容: 在工具选项板中,当我使用表单时,有 10 个
我有我的自定义集合属性,当它是我的组件的直接成员时,它工作得很好。 但我想将集合属性移动到组件内的 TPersistent 属性。现在问题来了,它不起作用:双击对象检查器中的集合属性通常会打开集合编辑
我正在更新组件中的一些属性。为了避免丢失属性错误,我使用 DefineProperties 从流中读取旧属性。大多数属性都工作正常,例如整数,但我无法使基于TPercient的属性发挥作用。 TRea
我对如何从具有 TPersistent 字段的 TComponent 中写出属性感到非常困惑。例如我有: TChildObj = class( TPersistent ) PRIVATE
我是一名优秀的程序员,十分优秀!