如何解决 DSServerModule1.ClientHeight: 属性 不存在错误

How to solve DSServerModule1.ClientHeight: Property does not exist error

我写了一个使用 firebird 数据库的应用程序,使用服务器和客户端。我最初使用 Delphi XE2 对应用程序进行编码并且一切正常。我现在已经转移到 Delphi XE6。

我重新编译了服务器并且没有错误,但是现在我重新编译了客户端却出现了以下错误:

ProjectPiping.exe raised execption class TDBXError with message "Remote error: Error reading DSServerModule1.ClientHeight: Propery CliehtHeight does not exist.

我在网上看到您需要将 dfm 文件 ontop 从 Object 更改为 Inherinted 但这没有任何区别。

有没有人可以帮助我,因为我无论如何都看不到我可以解决这个问题,除非回到 Delphi XE2

缺少 属性 错误对于 FramesDataModules 来说很常见,它们不直接继承自基础 Delphi TFrameTDataModule class。在某些情况下(随每个 Delphi 版本而变化)Delphi 将无法访问 FrameDataModule 祖先以确定它是否处理 TFrameTDataModule 个后代。发生这种情况时,它会错误地将 Frame/DataModule 解释为 Form,并用 Form 特定属性污染它们的 .dfm

您不必回滚到 XE2,您可以通过使用 Notepad 或类似编辑器从 .dfm 文件中删除 bad 属性来解决这个问题.由于这是您在对此类 Frame/DataModule 进行设计工作时必然会经常重复的操作,因此版本控制可以提供很大的帮助。只是不要提交不应该存在的更改。另一种防止 .dfm 文件中的零星更改的方法是在完成设计时使用它们后将它们设置为只读。

更正空 DataModule .dfm 文件:

inherited DataModule1: TDataModule1
  OldCreateOrder = False
  Height = 150
  Width = 215
end

破空DataModule .dfm文件

object DataModule1: TDataModule1
  Left = 0
  Top = 0
  ClientHeight = 188
  ClientWidth = 303
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
end

此问题是由卸载、禁用或以其他方式无法访问的设计(组件)包引起的。如果 Delphi 无法找到数据模块继承的组件,它会 will/may 更改 dfm 文件并用它知道的最有可能的候选者替换其属性。因为dfm与UI相关 Delphi会默认把对象当成一个TForm,相应地改变dfm中的属性和事件。但是,源代码(谢天谢地)与这些更改不同步,因此 属性 在尝试使用数据模块时不存在错误消息。代码和 dfm 不同步。

将对象更改为继承不是解决方案。您必须先重新安装或启用缺少的组件包,关闭 Delphi 然后用记事本编辑并保存 dfm。或者更好的是,在您的版本控制系统中恢复到以前的声音版本。如果没有选择(什么?!),那么您只需从 dfm 中删除不良属性和事件(或全部)即可恢复所有默认属性和事件。下次您在 Delphi 中打开 dfm 时,它将恢复为有效的默认值。

您可以通过不忽略 Delphi IDE 中的 "Property does not exists" 错误而是使用取消选项来防止将来出现此问题。这将阻止 changing/saving dfm,项目将在 运行 时间内正常运行。

这个变通办法将允许您的 DataModule 无论如何被创建,通过拦截和忽略关于不存在的 TForm 属性的错误 Delphi 正在插入您的 dfm (这只是一个变通办法,不是您遇到的 IDE 问题的解决方案)

1) 将这些声明添加到您的数据模块 class:

 private
    FSaveReaderOnError:TReaderError;
    procedure OnReaderError(Reader: TReader; const Message: string; var Handled: Boolean);
 protected
    procedure ReadState(Reader: TReader); override;

我们覆盖的 ReadState 方法负责加载 DFM,它使用 Reader:TReader 对象来完成。

TReader 公开了一个我们可以拦截以忽略错误的事件处理程序:

procedure TMyDataModule.ReadState(Reader: TReader);
begin
   FSaveReaderOnError := Reader.OnError;
   try
      // install our error handler 
      reader.OnError := self.OnReaderError;
      // let the dfm loading continue
      inherited;
   finally
      // restore previous error handler
      Reader.OnError := FSaveReaderOnError;
      FSaveReaderOnError := nil;
   end;
end;

这是错误处理程序:

procedure TMyDataModule.OnReaderError(Reader: TReader; const Message: string; var Handled: Boolean);
var Ignora:boolean;
    tmp:string;
begin
   if Assigned(FSaveReaderOnError) then begin
      // in case there already was an error handler, we call if first
      FSaveReaderOnError(Reader,Message,Handled);
      if handled = true then
          exit;     
   end;

   // ignore errors about missing form properties  
   if not message.StartsWith('Error reading '+self.name) then exit;
   if not message.EndsWith(' does not exist') then exit;
   if not message.Contains(' Property ') then exit;

   Handled := true;
   if message.Contains('Font')  then exit;
   if message.Contains('ClientHeight')  then exit;
   if message.Contains('ClientWidth')  then exit;
   if message.Contains('Color')  then exit;
   if message.Contains('PixelsPerInch')  then exit;
   if message.Contains('TextHeight')  then exit;
   Handled := false;
end;