关于TList属性存储的问题。(100分)

  • 主题发起人 主题发起人 angle_man
  • 开始时间 开始时间
A

angle_man

Unregistered / Unconfirmed
GUEST, unregistred user!
我做了一个控件,有个属性编辑器,有一个listview,我想把listview的内容存
在Tlist中,在一个工程编辑的时候没有问题。可我存盘退出后在打开这个工程,listview
内容总是空。我试过用TStrings存储listview的一列没有问题,可Tlist为什么不能保存呢。
请高手指教。部分代码如下:
TConPropList=Record
ControlName : String;
ControlProp : String;
OPC_Group : String;
OPC_Item : string;
Description : String;
end;
TControlsProperty = class(TClassProperty)
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes; override;
end;

TControlsEditProperty = class(TDefaultEditor)
protected
procedure EditProperty(PropertyEditor: TPropertyEditor;
var Continue, FreeEditor: Boolean); override;
end;
TOPCControlList=class(TPersistent) //TComponent
private
FItemList:TStrings;
FOnChange: TNotifyEvent;
FConPropList:TArrayConPropList;
FHasData:Boolean;
FList:TList;
FConPropList1:TConPropList;
function GetList:TList;
procedure SetList(Value:TList);
protected
//procedure ReadData(Reader: TReader); virtual;
//procedure WriteData(Writer: TWriter); virtual;
//procedure DefineProperties(Filer: TFiler); override;
public
procedure Changed;
procedure SetItemList(Value:TStrings);
procedure Init;
destructor Destroy;override;
published
property Items:TStrings read FItemList write SetItemList;
property ConPropList:TList read GetList write SetList;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;

procedure TControlsProperty.Edit;

{procedure ParseText(var Lines : TStrings; const S : String);
var
x : Integer;
Temp : String;
begin
if (S <> '') then begin
Temp := '';
for x := 1 to Length(S) do begin
if S[x] = #13 then begin
Lines.Add(Temp);
Temp := '';
end else
Temp := Temp + S[x];
end;
if (Temp <> '') then Lines.Add(Temp);
end;
end;

procedure ExtractText(Lines : TStrings; var S : String);
var
x : Integer;
begin
for x := 0 to Lines.Count - 1 do begin
if (x <> 0) then S := S + #13;
S := S + Lines[x];
end
end; }

var
TempOPCControls:TOPCControlList;
i:Integer;
PConList:^TConPropList;
Item:TListItem;
ListView:TListView;
frmCon:TfrmControl;
TempStr:TStrings;
begin
TempOPCControls := TOPCControlList(GetOrdValue);
frmCon:=TfrmControl.create(nil);
With frmCon do
begin
try
ListView1.Items.Clear;

For i:=0 to TempOPCControls.FList.Count-1 do
begin
Item := ListView1.Items.Add;
New(PConList);
PConList:=TempOPCControls.ConPropList.Items;
showmessage(PConList^.ControlName);
Item.Caption := PConList^.ControlName;
Item.SubItems.Add(PConList^.ControlProp);
Item.SubItems.Add(PConList^.OPC_Group);
Item.SubItems.Add(PConList^.OPC_Item);
Item.SubItems.Add(PConList^.Description);
Dispose(PConlist);
end;
ListControl.Items.clear;
tempstr:=TStringList.create;
TempStr.addStrings(TempOPCControls.FItemList);
ListControl.Items.AddStrings(TempStr);

{ Item := ListView1.Items.Add;
Item.Caption:=TempOPCControls.FConPropList1.ControlName;}

if showmodal = mrok then
begin
SetLength(TempOPCControls.FConPropList,ListView1.Items.Count);
TempOPCControls.ConPropList.Clear;
For i:=0 to ListView1.Items.Count-1 do
begin
with TempOPCControls.FConPropList,ListView1.Items.Item do
begin
ControlName := Caption;
ControlProp := SubItems[0];
OPC_Group := SubItems[1];
OPC_Item := SubItems[2];
Description := SubItems[3];
new(PConList);
PConList^.ControlName := Caption;
PConList^.ControlProp := SubItems[0];
PConList^.OPC_Group := SubItems[1];
PConList^.OPC_Item := SubItems[2];
PConList^.Description := SubItems[3];
TempOPCControls.ConPropList.Add(PConList);
end;
end;
TempOPCControls.FItemList.clear;
TempOPCControls.FItemList.AddStrings(Listcontrol.Items);
//TempOPCControls.FConPropList1.ControlName:=ListView1.Items.Item[0].Caption;

SetOrdValue(LongInt(TempOPCControls));
end;
finally
tempstr.free;
Free;
end;
end;
end;

function TControlsProperty.GetAttributes: TPropertyAttributes;
begin
result:=inherited GetAttributes+[paDialog,paReadOnly]-[paSubProperties];
end;

{------------------------------------------------------------------------------ }
{-------TControlsEditProperty----------}
{------------------------------------------------------------------------------ }
procedure TControlsEditProperty.EditProperty(PropertyEditor: TPropertyEditor;
var Continue, FreeEditor: Boolean);
var
PropName: string;
begin
PropName := PropertyEditor.GetName;
if (CompareText(PropName, 'ControlList') = 0) then
begin
PropertyEditor.Edit;
Continue := False;
end;
end;
{------------------------------------------------------------------------------ }
{-------TOPCControlList------}
{-------------------------------------------------------------------------------}

procedure TOPCControlList.Init;
begin
FItemList:=TStringList.Create;
FList := TList.Create;
end;

{constructor TOPCControlList.Create(AOwner:TComponent);
begin
FItemList:=TStringList.Create;
FList := TList.Create;
end; }

destructor TOPCControlList.Destroy;
begin
FItemList.Free;
//FList.Clear;
FList.Free;
inherited Destroy;
end;

procedure TOPCControlList.SetItemList(Value:TStrings);
begin
if Value <> FItemList then
begin
FItemList := Value;
Changed;
end;
end;

function TOPCControlList.GetList:TList;
begin
Result:=FList;
end;

procedure TOPCControlList.SetList(Value:TList);
begin
FHasData:=True;
FList:=Value;
end;

function TOPCControlList.GetList1:TConPropList;
begin
Result:=FConPropList1;
end;

procedure TOPCControlList.SetList1(Value:TConPropList);
begin
FHasData:=True;
FConPropList1:=Value;
end;

procedure TOPCControlList.Changed;
begin
if Assigned(FOnChange) then FOnChange(Self);
end;

{procedure TOPCControlList.ReadData(Reader: TReader);
begin
//if Reader.ReadBoolean then
// FList := TList(Reader.ReadComponent(nil));
// with FConPropList1 do
// begin
// ControlName:=Reader.ReadString;
// ControlProp:=Reader.ReadString;
// OPC_Group:=Reader.ReadString;
// OPC_Item:=Reader.ReadString;
// Description:=Reader.ReadString;
// end;
end; }

{procedure TOPCControlList.WriteData(Writer: TWriter);
begin
// Writer.WriteBoolean(FList <> nil);
// if FList <> nil then
// Writer.WriteComponent(TComponent(FList));
// with FConPropList1 do
// begin
// Writer.WriteString(ControlName);
// Writer.WriteString(ControlProp);
// Writer.WriteString(OPC_Group);
// Writer.WriteString(OPC_Item);
// Writer.WriteString(Description);
// end;
end; }

{procedure TOPCControlList.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty('ConPropListData', ReadData, WriteData, FHasData);
end; }
 
判断属性值修改后调用:
PropertyEditor.Designer.Modified;
 
在哪里添加 PropertyEditor.Designer.Modified;
 
对于TList指向的对象,你可以重载控件的GetChildren方法,告诉IDE去保存TList中的对象
类似下面
procedure TXXXControl.GetChildren(Proc: TGetChildProc;
Root: TComponent);
var
I: Integer;
begin
inherited GetChildren(Proc, Root);
for I := 0 to FList.Count - 1 do
begin
Proc(TXXXChildren(FList.Items));
end;
end;
另外你的子对象不要声明为record,最好声明为TComponent,必须实现HasParent, SetParentComponent,GetParentComponent等方法
很麻烦的,你看VCL的源码吧
或者你也可以用DefineProperty方法。

TStrings能保存是因为Borland内置的TWriter类提供了WriteListBegin,WriteListEnd方法可以用来
保存字符串列表。
 
后退
顶部