【问题标题】:Custom property flow reading error自定义属性流读取错误
【发布时间】:2013-12-17 10:08:47
【问题描述】:

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

错误信息(法语):

1

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é

2

TPedroGraphLineCollectionItem.□□: la propriété □□ n'existe pas. 错误。 Ignorer l'erreur et continuer ?Remarque: ceci peut provoquer la suppress de composants ou la perte de valeurs de propriété

注意:'□' 字符实际上是这样显示的。

3

TPedroGraphLineCollectionItem.□□

4

Erreur lors de la Lecture de PedroGraphLines1.Lines: Valeur de propriété wronge。 Ignorer l'erreur et continuer ?Remarque: ceci peut provoquer la suppress de composants ou la perte de valeurs de propriété

5

Erreur à la création de la fiche : Erreur de Lecture du Flux.

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;

我哪里错了?

【问题讨论】:

  • 转到项目选项,设置“使用调试 DCU”复选框,然后在 TPedroGraphLineCollectionIem.ReadListDataTPedroGraphLineCollectionIem.DefineProperties 中放置断点,并像调试其他所有内容一样调试 DFM 加载过程。然后回过头来说出究竟是哪一行导致了错误。包括复制异常的逐字文本(可以只是从异常对话框中复制粘贴为文本)
  • 我已经尝试过了,没有任何改变。当我谈论加载表单时,我的意思是在 EDI 中并且不使用断点。
  • 您可以从另一个 IDE 运行一个 IDE 来调试组件 - 阅读有关使用“主机应用程序”(这将是 IDE 的另一个副本)调试 DLL 和 BPL(并且您的组件是 BPL)的信息 // 也异常文本的逐字复制无论如何都是问题的适当部分,DFM 源也是如此 - 只需将它们设为您的组件,仅此而已 // 您也不需要在 IDE 中打开表单来编译、运行和调试该程序。只需在不打开表单的情况下进行调试。

标签: delphi properties delphi-2010 custom-component dfm


【解决方案1】:

我认为你错过了DefinePropertypublished 的重点 它们是相互排斥的。

  • 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 您是否亲自阅读过 DFM 资源?你没有在这里复制 DFM,所以我不能为你做。我只能重复:你的 DFM 是什么?可能是“PointList”在那里存储了两次 - 作为列表和组件?
  • 这里是 .dfm:InternalPointList = ( 1 2 3 4) 不,PointList 属性从未存储过两次 ;)
  • 它是新 dfm 的一部分,我说的是整个旧 dfm,您可能会看到尚未修复的错误(好吧,您也没有报告错误文本)。我很幸运能猜到您的问题,但下次请提供逐字逐句的具体信息以进行调试。 sscce.orgcatb.org/~esr/faqs/smart-questions.html
猜你喜欢
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 2022-10-05
  • 2020-10-15
  • 1970-01-01
  • 2021-12-03
相关资源
最近更新 更多