【问题标题】:Delphi: EReadError with message ‘Property PageNr does Not Exist’Delphi:带有消息“Property PageNr 不存在”的 EReadError
【发布时间】:2010-04-21 11:53:25
【问题描述】:

当我尝试运行自己的项目时,有时会收到错误消息:EReadError 并显示消息“Property PageNr 不存在”。我真的很绝望,因为我根本看不出是什么原因。可怕的是它有时但经常出现。它涉及我自己的组件 TPage。这是声明>

TPage = class(TCustomControl)   //
   private
      FPaperHeight, FPaperWidth:Integer;
      FPaperBrush:TBrush;
      FPaperSize:TPaperSize;
      FPaperOrientation:TPaperOrientation;
      FPDFDocument: TPDFDocument;
      FPageNr:integer;

      procedure PaintBasicLayout;
      procedure PaintInterior;
      procedure SetPapersize(Value: TPapersize);
      procedure SetPaperHeight(Value: Integer);
      procedure SetPaperWidth(Value: Integer);
      procedure SetPaperOrientation(value:TPaperOrientation);
      procedure SetPaperBrush(Value:TBrush);
      procedure SetPageNr(Value:Integer);
   protected
      procedure CreateParams(var Params:TCreateParams); override;
      procedure AdjustClientRect(var Rect: TRect); override;
   public
      constructor Create(AOwner: TComponent);override;
      destructor Destroy;override;
//      function GetChildOwner:TComponent; override;
      procedure DrawControl(X,Y :integer; Dx,Dy:Double; Ctrl:TControl;NewCanvas:TCanvas);
//      procedure GetChildren(Proc:TGetChildProc; Root:TComponent); override;
      procedure Loaded; override;
      procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);  override;
      procedure Paint; override;
      procedure PrintOnCanvas(X,Y:integer; rX,rY:Double; ACanvas:TCanvas);
      procedure PrintOnPDFCanvas(X,Y:integer);
      procedure PrintOnPrinterCanvas(X,Y:integer);
      procedure Resize; override;
      procedure SetPrintKind(APrintKind:TPrintKind; APrintGroupindex:Integer);
   published
      property PageNr:integer read FPageNr write SetPageNr;
      property PaperBrush: TBrush read FPaperBrush  write SetPaperBrush;
      property PaperHeight: integer read FPaperHeight write SetPaperHeight;
      property PaperWidth: integer read FPaperWidth write SetPaperWidth;
      property PaperSize: TPaperSize read FPaperSize write SetPaperSize;
      property PaperOrientation:TPaperOrientation read FPaperOrientation write SetPaperOrientation;
      property PDFDocument:TPDFDocument read FPDFDocument write FPDFDocument;
      property TabOrder;
   end;

我彻底阅读了此处描述的类似主题:

Delphi: EReadError with message 'Property Persistence does Not exist'

但这里是我自己的源代码。没有第三方。有趣的是:当我在我的 dfm 文件(unit1.dfm)中删除 PageNr 属性时,会弹出:EReadError 并带有消息“Property PaperHeight 不存在”。当我删除 PaperHeight 然后它会要求 PaperWidth 等等......

这是一段 dfm 文件:

 object pg1: TPage
    Left = 128
    Top = 144
    Width = 798
    Height = 1127
    PageNr = 0
    PaperHeight = 1123
    PaperWidth = 794
    PaperSize = psA4
    PaperOrientation = poPortrait
    TabOrder = 0
    object bscshp4: TBasicShape
      Left = 112
      Top = 64
      Width = 105
      Height = 105
      PrintKind = pkNormal
      PrintGroupIndex = 0
      Zooming = 100
      Transparent = False
      Repeating = False
      PageRepeatOffset = 1
      ShapeStyle = ssVertical
      LinePosition = 2
    end
    object bscshp5: TBasicShape
      Left = 288
      Top = 24
      Width = 105
      Height = 105
      PrintKind = pkNormal
      PrintGroupIndex = 0
      Zooming = 100
      Transparent = False

到底发生了什么???????我从来没有见过。我多次编译单元...遇到没有问题。也许原因不止于此。我感到完全无能为力。

【问题讨论】:

  • TPage 不会与您系统上安装的现有组件发生冲突吗?

标签: delphi


【解决方案1】:

您在这里遇到的是类型名称冲突。

ExtCtrls 中有一个名为 TPage 的类。如果 ExtCtrls 列在单元接口部分的 uses 子句中,Delphi 将“假定”您指的是最后声明的 TPage - 它具有完全不同的属性。

如果您要添加一些与 TPage 对象交互的代码,类完成将显示 ExtCtrls.TPage 的方法和属性,而不是您的 TPage。这就是重命名为 TBookPage 解决问题的原因。

最好在您自己的控件上使用短前缀以避免这种情况(例如,使用 TLyPage)。这就是大多数第 3 方控件使用类似方案的原因。

这可以用作重新实现控件的快捷方式 - 请参阅 Deltics Blog entry 以获取示例。

【讨论】:

  • 这是一个名称冲突,但它与uses子句中的单位顺序无关。表单编辑器中可用的每个组件都已使用 RegisterClass(TComponentName) 进行了注册。这允许 IDE 按名称 找到类,然后调用它的虚拟构造函数 (Create)。不幸的是(并且令人震惊地难以置信)当您尝试使用不同的类再次注册类(TComponentName)时,Delphi 不会抛出错误!由于名称冲突,IDE 加载了错误的 TPage,然后它尝试使用 RTTI 查找 PageNr 属性来设置它——显然失败了。
  • 我的上帝,非常非常感谢你投来了一缕启蒙。真的,我检查了 ExtCtrls,是的 - 有 TPage。我也是这么想的,所以我尝试在Delphi的帮助下找到TPage。但是没有描述这样的类,所以我停止了进一步的搜索......然而,当我使用 TBookPage 运行应用程序时,我仍然感到脖子发痒。下次我一定会用前缀命名我的组件......我会在几天后接受你的回答,如果一切都好......无论如何都要感谢...... :-)
  • 此外,我发现在 ExtCtrls 中引入的 TPage 是 TCustomControl - 和我的完全一样。所以这可能导致了混乱。 (没有错误抛出,等等......)!
  • @Cosmin,我怀疑你就在这里。我忘记了这件事的细节。在这种情况下,如果 RegisterClass 抛出异常就好了。
  • @Lyborko - 似乎 TPage 已经被 Delphi 帮助排除了很长时间 - 例如见 esanu.name/delphi/Components/…。它在docwiki.embarcadero.com/VCL/en/ExtCtrls.TPage_Members
【解决方案2】:

检查硬盘上 .DFM 文件的多个副本。当实际链接到可执行文件的 .DFM 不是您在 IDE 中看到的文件时,通常会发生这种情况。

另外,您是否使用运行时包进行构建?也可能是您的应用程序正在构建的包版本与运行时加载的包版本不同。加载 .DFM 属性的错误可能来自包寻找应用程序中不存在的东西(或者更有可能,反之亦然 - 应用程序期望从包中加载 .DFM 时不存在于包中的东西)。

【讨论】:

  • 以上是我自己2天前写的组件。在界面中,我引用了各种单元,它们是其他包的一部分。我在默认目录中编译项目。单元 1.pas,单元 1.dfm。没有其他 Unit1.dfm。但是 PageNr 属性正常存在并被声明。我也在 Objectinspector 中看到它...有时会发生,最好的做法似乎是重新启动 Windows... 现在我取消注册 TPage 并注册 TBookPage。看起来它到目前为止有效。我稍后再看,会发生什么……
猜你喜欢
  • 1970-01-01
  • 2014-07-15
  • 1970-01-01
  • 2018-03-24
  • 1970-01-01
  • 1970-01-01
  • 2018-09-20
  • 2015-08-28
  • 1970-01-01
相关资源
最近更新 更多