自定义属性流读取错误
我是Delphi 2010的法语用户,请原谅我的英语不好。自定义属性流读取错误
我从TCustomControl创建了一个控件。此控件具有由TCollectionItem后裔填充的TOwnedCollection。 这些项目具有已发布的自定义列表属性。这个列表是我制作的一对整数列表。 我已经为此属性编写了一个自定义设计时编辑器,并且它完美地工作。 所以现在,我想将列表数据写入dfm中,并且变得有点困难。
这里是我做了什么:
TPedroGraphLineCollectionIem = class(TCollectionItem)
published
property PointList: TPedroIntegerCoupleList read FList write SetList
stored GetStored;
...
procedure TPedroGraphLineCollectionIem.DefineProperties(Filer: TFiler);
begin
inherited;
//'PointList' : the property name
//FList.Count > 0 : Is the list empty ?
Filer.DefineProperty('PointList', ReadListData, WriteListData,
(FList.Count > 0));
end;
...
procedure TPedroGraphLineCollectionIem.ReadListData(Reader: TReader);
var
Val1, Val2: Integer;
begin
with Reader do
begin
ReadListBegin;
while not EndOfList do
begin
Val1 := ReadInteger;
Val2 := ReadInteger;
FList.AddCouple(Val1, Val2);
end;
ReadListEnd;
end;
end;
...
procedure TPedroGraphLineCollectionIem.WriteListData(Writer: TWriter);
var
I: Integer;
begin
with Writer do
begin
WriteListBegin;
for I := 0 to Count - 1 do
begin
WriteInteger(FList[I].Value1);
WriteInteger(FList[I].Value2);
end;
WriteListEnd;
end;
end;
的WriteListData程序完美的作品和值写入DFM。但是当我尝试加载表单时,它总是崩溃,对话框告诉我这个属性有一个阅读流错误。
FList是在类的构造函数内部创建的。
这里是.DFM:
object MainFrm: TMainFrm
Left = 0
Top = 0
Caption = 'MainFrm'
ClientHeight = 425
ClientWidth = 689
Color = clBtnFace
ParentFont = True
OldCreateOrder = False
Position = poScreenCenter
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object PedroGraph1: TPedroGraph
Left = 120
Top = 136
Width = 313
Height = 209
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
Lines = <
item
LinePen.Color = clRed
PointList = (
1
2
3
4)
end>
MarksFont.Charset = DEFAULT_CHARSET
MarksFont.Color = clWindowText
MarksFont.Height = -11
MarksFont.Name = 'Tahoma'
MarksFont.Style = []
end
end
错误消息(法语):
Erreur lors de la lecture de TPedroGraphLineCollectionItem.PointList: Valeur de propriété incorrecte. Ignorer l'erreur et continuer ?Remarque: ceci peut provoquer la suppression de composants ou la perte de valeurs de propriété
ERREUR的LOR德拉讲座德TPedroGraphLineCollectionItem □□:lapropriété□n'exist e pas。 Ignorer L'ERREUR等continuer雷马克:CECI peut provoquer LA抑制德composants欧拉perte德valeurs德propriété
注: '□' 字符确实显示这一点。
ERREUR的LOR德拉讲座德TPedroGraphLineCollectionItem□□
ERREUR的LOR德拉讲课德PedroGraphLines1.Lines:Valeur德propriétéincorrecte。 Ignorer L'ERREUR等continuer雷马克:CECI peut provoquer LA抑制去composants欧拉perte德valeurs德propriété
ERREUR点菜CRÉATION德拉平片:ERREUR德演讲杜通量。
TPedroIntegerCoupleList宣言:
TPedroIntegerCouple = record
Value1: Integer;
Value2: Integer;
end;
TPedroGenericList<T> = class(TList<T>)
private
FOnChange: TNotifyEvent;
FUpdating: Boolean;
protected
procedure Notify(const Item: T; Action: TCollectionNotification); override;
procedure DoChange;
published
public
constructor Create;
procedure SortCustom; virtual; abstract;
procedure Assign(const Source: TPedroGenericList<T>);
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
TPedroIntegerCoupleList = class(TPedroGenericList<TPedroIntegerCouple>)
private
function GetString: String;
procedure SetString(const Value: String);
public
procedure SortCustom; override;
function AddCouple(const Value1, Value2: Integer): Integer;
procedure InsertCouple(const Index, Value1, Value2: Integer);
property AsString: String read GetString write SetString;
end;
我在哪里错了?
我想你错过了点DefineProperty
和published
他们是互斥的。
-
published
意味着VCL将通过它自己的方式存储不动产。 -
DefineProperty
意味着没有这样的不动产,但你会假装像是有虚拟的。
什么是您的DFM?可能是'PointList'在那里存储了两次 - 作为列表和组件?
如果是这样 - 你应该只选择一种方法来保存它以某种方式,例如使属性PUBLIC而不是PUBLISHED。
或者,也许你可以尝试让非撞击的名字,像
property PointList: TPedroIntegerCoupleList read FList write SetList stored FALSE;
Filer.DefineProperty('PointList_Virtual_DATA', ....
@Pedrault等错在哪里以及如何修复它? –
是的!有用 !我修改了发布的属性存储为false,我已经定义了一个InternalPointList属性,它的工作原理!尽管如此,我已经想到了你所说的:发布的属性会自动写入。但是,使用WriteListData将数据正确写入dfm中......好了!非常感谢 !! – Pedrault
@Pedrault您是否亲自阅读过DFM源代码?你没有在这里复制DFM,所以我不能为你做。我只能重复一遍:*你的DFM是什么? ?可能它是“PointList”被存储在那里的两倍 - 作为列表和作为组分* –
转到项目选项,设置“使用调试DCU的”复选框,然后放在'TPedroGraphLineCollectionIem.ReadListData'以及'TPedroGraphLineCollectionIem断点。 DefineProperties'并调试DFM加载过程,就像调试其他一切一样。然后回来,说出哪一行确实会导致错误。包括复制异常的逐字文本(它可以从异常对话框复制粘贴为文本) –
我试过这个,没有任何改变。当我谈论加载表单时,我的意思是在EDI中不使用断点。 – Pedrault
您可以从另一个IDE运行一个IDE来调试组件 - 使用“主机应用程序”(这可能是IDE的另一个副本)阅读有关调试DLL和BPL(以及您的组件是BPL)的信息//也可逐字拷贝异常文本成为问题的适当部分,以及DFM源代码 - 仅仅让它们成为你的组件,而不需要其他东西//你也不需要在IDE中打开窗体来编译,运行和调试程序。只需调试它而不打开窗体。 –