2013-12-17 106 views
0

我是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; 

我在哪裏錯了?

+0

轉到項目選項,設置「使用調試DCU的」複選框,然後放在'TPedroGraphLineCollectionIem.ReadListData'以及'TPedroGraphLineCollectionIem斷點。 DefineProperties'並調試DFM加載過程,就像調試其他一切一樣。然後回來,說出哪一行確實會導致錯誤。包括複製異常的逐字文本(它可以從異常對話框複製粘貼爲文本) –

+0

我試過這個,沒有任何改變。當我談論加載表單時,我的意思是在EDI中不使用斷點。 – Pedrault

+0

您可以從另一個IDE運行一個IDE來調試組件 - 使用「主機應用程序」(這可能是IDE的另一個副本)閱讀有關調試DLL和BPL(以及您的組件是BPL)的信息//也可逐字拷貝異常文本成爲問題的適當部分,以及DFM源代碼 - 僅僅讓它們成爲你的組件,而不需要其他東西//你也不需要在IDE中打開窗體來編譯,運行和調試程序。只需調試它而不打開窗體。 –

回答

2

我想你錯過了點DefinePropertypublished 他們是互斥的。

  • published意味着VCL將通過它自己的方式存儲不動產。
  • DefineProperty意味着沒有這樣的不動產,但你會假裝像是有虛擬的。

什麼是您的DFM?可能是'PointList'在那裏存儲了兩次 - 作爲列表和組件?

如果是這樣 - 你應該只選擇一種方法來保存它以某種方式,例如使屬性PUBLIC而不是PUBLISHED。

或者,也許你可以嘗試讓非撞擊的名字,像

property PointList: TPedroIntegerCoupleList read FList write SetList stored FALSE; 

Filer.DefineProperty('PointList_Virtual_DATA', .... 
+0

@Pedrault等錯在哪裏以及如何修復它? –

+0

是的!有用 !我修改了發佈的屬性存儲爲false,我已經定義了一個InternalPointList屬性,它的工作原理!儘管如此,我已經想到了你所說的:發佈的屬性會自動寫入。但是,使用WriteListData將數據正確寫入dfm中......好了!非常感謝 !! – Pedrault

+0

@Pedrault您是否親自閱讀過DFM源代碼?你沒有在這裏複製DFM,所以我不能爲你做。我只能重複一遍:*你的DFM是什麼? ?可能它是「PointList」被存儲在那裏的兩倍 - 作爲列表和作爲組分* –

相關問題