VCL控件中自定义的对象属性保存不了(请进来看看) (100分)

  • 主题发起人 主题发起人 zyycc
  • 开始时间 开始时间
Z

zyycc

Unregistered / Unconfirmed
GUEST, unregistred user!
我定义了一个类,其内部包含了几个字符串及嵌套了包含字符串的对象,
然后,再将其放如ADOQuery中published,但在属性编辑中编辑后,关闭项目
再打开,发现刚才的修改并未保存,请大家帮帮忙。
代码如下
---ifc.pas------

unit Ifc;

interface

uses Classes;

type

TSQLFields = class(TPersistent)
private
FOriFields: TStrings;
FOutFields: TStrings;
procedure SetOriFields(const value:TStrings);
procedure SetOutFields(const value:TStrings);
public
constructor Create; //override;
destructor Destroy; override;
published
property OriFields:TStrings read FOriFields write SetOriFields;
property OutFields:TStrings read FOutFields write SetOutFields;
end;

TSQLstm = class(TPersistent)
private
FOriSQL: TStrings;
FWhere: TStrings;
FOrder: TStrings;
FSQLFields: TSQLFields;
FVersion:TStrings;
procedure SetOriSQL(const value:TStrings);
procedure SetWhere(const value:TStrings);
procedure SetOrder(const value:TStrings);
public
constructor Create; //override;
destructor Destroy; override;
published
property OriSQL:TStrings read FOriSQL write SetOriSQL;
property Where: TStrings read FWhere write SetWhere;
property Order: TStrings read FOrder write SetOrder;
property SQLFields: TSQLFields read FSQLFields;
end;

implementation

{ TSQLFields }


constructor TSQLFields.Create;
begin
inherited;// Create;
FOriFields := TStringList.Create;
FOutFields := TStringList.Create;
end;

destructor TSQLFields.Destroy;
begin
FOriFields.Destroy;
FOutFields.Destroy;
inherited;
end;

procedure TSQLFields.SetOriFields(const value: TStrings);
begin
FOriFields.Add(value.Text);
end;

procedure TSQLFields.SetOutFields(const value: TStrings);
begin
FOutFields.AddStrings(value);
end;


{ TSQLstm }

constructor TSQLstm.Create;
begin
inherited;// Create;
FOriSQL:=TStringList.Create;
FWhere:=TStringList.Create;
FOrder:=TStringList.Create;
FSQLFields:=TSQLFields.Create;
end;


destructor TSQLstm.Destroy;
begin
FOriSQL.Destroy;
FWhere.Destroy;
FOrder.Destroy;
FVersion.Destroy;
FFilter.Destroy;
FSQLFields.Destroy;
inherited;
end;


procedure TSQLstm.SetOrder(const value: TStrings);
begin
FOrder.AddStrings(value);
end;

procedure TSQLstm.SetOriSQL(const value: TStrings);
begin
FOriSQL.AddStrings(value);
end;


procedure TSQLstm.SetWhere(const value: TStrings);
begin
FWhere.AddStrings(value);
end;

end.

---ZyADOQry.pas---
unit zyADOQry;

interface

uses Ifc,SysUtils,DB, ADODB,Classes;

type

TzyADOQry = class(TADOQuery)
private
FSQLstm: TSQLstm;
function GetCmpValue:Boolean;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Changed:Boolean read GetCmpValue default false;
property SQLstm:TSQLstm read FSQLstm;
end;

//TSQLstmProperty = class(TPropertyEditor)
// function GetAttributes:TPropertyAttributes; override;
// function GetValue:string; override;
// end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('ZyCtrls', [TzyADOQry]);
end;

{ TzyADOQry }

function TzyADOQry.GetCmpValue;
var i:integer;
begin
Result:=False;
if Self.Active=True then
begin
for i:=0 to Self.FieldCount-1 do
begin
if not (TrimRight(string(Self.Fields.Value)) = TrimRight(string(Self.Fields.OldValue))) then
begin
Result:=True;
break;
end;
end;
end;
end;

constructor TzyADOQry.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FSQLstm := TSQLstm.Create;
end;

destructor TzyADOQry.Destroy;
begin
FSQLstm.Destroy;
inherited;
end;
end.
 
setsubcomponent....
就行了,具体看一下vcl源码就知道了
 
谢谢dedema,我还是不太明白,SetSubComponet是TComponet的方法,但我的自定义对象是从TPersistent继承来的,能否再说详细些
 
TSQLstm 改为从TComponent集成,
然后setsubcomponent
 
To:book523
我将TSQLstm及TSQLFields都改成从TComponent继成后,可以保存值了,在属性编辑器里,SQLstm及
SQLFields的值变成了zyADOQuery1,而不是之前的TSQLstm TSQLFields,
但感觉不是很完美,如TParameters也是从TPersisent继承,却可保存,又是为什么呢。
 
TPersistent继承的类必须自己来读写自己的数据
主要是要覆盖一个方法
procedure DefineProperties(Filer: TFiler); override;

一个例子如下:
procedure TStrings.DefineProperties(Filer: TFiler);

function DoWrite: Boolean;
begin
if Filer.Ancestor <> nil then
begin
Result := True;
if Filer.Ancestor is TStrings then
Result := not Equals(TStrings(Filer.Ancestor))
end
else Result := Count > 0;
end;

begin
Filer.DefineProperty('Strings', ReadData, WriteData, DoWrite);
end;

procedure TStrings.ReadData(Reader: TReader);
begin
Reader.ReadListBegin;
BeginUpdate;
try
Clear;
while not Reader.EndOfList do Add(Reader.ReadString);
finally
EndUpdate;
end;
Reader.ReadListEnd;
end;

procedure TStrings.WriteData(Writer: TWriter);
var
I: Integer;
begin
Writer.WriteListBegin;
for I := 0 to Count - 1 do Writer.WriteString(Get(I));
Writer.WriteListEnd;
end;
 
To:lich
可否解释一下上面的程序,或者说说我的程序该如何去写.
 
你需要覆盖我说的那个方法,
自己实现数据的保存
或者,你直接从TComponent继承,就不用自己写了
 
就像 book523, 所说的方法一样
 
掉帖了,再补一次,简单说一下:
将 property SQLFields: TSQLFields read FSQLFields;
改为: property SQLFields: TSQLFields read FSQLFields write SetSQLFields;
SetSQLFields 实现方法如下:
procedure TSQLstm.SetSQLFields(const Value: TSQLFields);
begin
FSQLFields.Assign(Value);
end;


如此,即可保存自定义属性.
 

Similar threads

I
回复
0
查看
510
import
I
I
回复
0
查看
750
import
I
I
回复
0
查看
549
import
I
I
回复
0
查看
524
import
I
I
回复
0
查看
654
import
I
后退
顶部