如何告诉 Delphi 不要在 DFM 中包含未发布的属性?
How to tell Delphi to not include non-published properties in DFM?
我有一个自定义控件:
type
TContosoFrobber = class(TCustomControl)
private
end;
在内部,我的组件创建了一个 control:
type
TContosoFrobber = class(TCustomControl)
private
FMyDateTimePicker: TDateTimePicker;
public
constructor Create(AOwner : TComponent); override;
property DateTimePicker: TDateTimePicker read FMyDateTimePicker;
end;
constructor TContosoFrobber.Create(AOwner: TComponent);
begin
inherted Create(AOwner);
FMyControl := TMyDateTimePicker.Create(AOwner);
end;
其中 TMyDateTimePicker 是 TDateTimePicker
的简单后代
TMyDateTimePicker = class(TDateTimePicker)
protected
end;
所以总结一下我做了什么:
- 声明一个私有变量
TDateTimePicker
- 将其公开为public(即非已发布)属性 [=17] =]
- 通过多态,控件实际上是
TDateTimePicker
的后代
这一切都有效 - 直到我最近重新安装 Delphi XE6(在 Windows 10)。
DFM
这就是为什么我无法理解为什么在设计时出现错误:
Class TMyDateTimePicker not found
为什么要查找 class? class 在实现细节中;它不是为流媒体发布的。流媒体系统是如何尝试创建它的!?所以我检查了 DFM:
object cfBeachBall: TContosoFrobber
Left = 445
Top = 25
Width = 101
Height = 22
...snip...
object TMyDateTimePicker
Left = 0
Top = 0
Width = 101
Height = 22
Date = 37306.581535243100000000
Time = 37306.581535243100000000
TabOrder = 0
TabStop = False
end
end
为什么 TInternalDateTimePicker
在 dfm 中结束:
- 属性 是 public,不是 发表的
如何阻止表单流系统在 dfm 中放置未发布的 属性?
更糟糕的是越野车IDE
它不仅有时包含一个 属性 不应该包含的内容。有时它包括 属性 它不应该 两次 :
object cfPlasticBag: TContosoFrobber
Left = 445
Top = 25
Width = 101
Height = 22
...snip...
object TMyDateTimePicker
Left = 0
Top = 0
Width = 101
Height = 22
Date = 37306.581535243100000000
Time = 37306.581535243100000000
TabOrder = 0
TabStop = False
end
object TMyDateTimePicker
Left = 0
Top = 0
Width = 101
Height = 22
Date = 37306.581535243100000000
Time = 37306.581535243100000000
TabOrder = 0
TabStop = False
end
end
- 如何阻止 dfm 包含未发布的属性?
- 如何阻止 dfm 包含它两次?
黑客解决方法
我知道可怕的黑客攻击:告诉 DFM 它不应该让任何业务知道的控件:
initialization
RegisterClass(TMyDateTimePicker);
finalization
UnRegisterClass(TMyDateTimePicker);
end.
现在 dfm 包含一个它不知道的控件。每次我保存表格时,它都会包含对不应该引用的内容的引用。最糟糕的是:我证实了它对 TMyDateTimePicker
的错误信念。
为什么DelphiXE6在重装前不这样做?也许我需要安装长期不受支持的 Delphi?
版本的最新更新
已知错误?
问题是您将错误的 Owner
分配给了 TDateTimePicker
。您正在指定 TContosoFrobber
的所有者而不是 TContosoFrobber
本身:
constructor TContosoFrobber.Create(AOwner: TComponent);
begin
inherted Create(AOwner);
FMyControl := TMyDateTimePicker.Create(Self); // <-- not AOwner!
end;
或者:如 Jerry Doge 所述,您可以改用 nil
所有者。您只需手动 Free()
TDataTimePicker
:
type
TContosoFrobber = class(TCustomControl)
private
FMyDateTimePicker: TDateTimePicker;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
...
end;
constructor TContosoFrobber.Create(AOwner: TComponent);
begin
inherted Create(AOwner);
FMyControl := TMyDateTimePicker.Create(nil);
end;
destructor TContosoFrobber.Destroy;
begin
FMyControl.Free;
inherted Destroy;
end;
我有一个自定义控件:
type
TContosoFrobber = class(TCustomControl)
private
end;
在内部,我的组件创建了一个 control:
type
TContosoFrobber = class(TCustomControl)
private
FMyDateTimePicker: TDateTimePicker;
public
constructor Create(AOwner : TComponent); override;
property DateTimePicker: TDateTimePicker read FMyDateTimePicker;
end;
constructor TContosoFrobber.Create(AOwner: TComponent);
begin
inherted Create(AOwner);
FMyControl := TMyDateTimePicker.Create(AOwner);
end;
其中 TMyDateTimePicker 是 TDateTimePicker
的简单后代TMyDateTimePicker = class(TDateTimePicker)
protected
end;
所以总结一下我做了什么:
- 声明一个私有变量
TDateTimePicker
- 将其公开为public(即非已发布)属性 [=17] =]
- 通过多态,控件实际上是
TDateTimePicker
的后代
这一切都有效 - 直到我最近重新安装 Delphi XE6(在 Windows 10)。
DFM
这就是为什么我无法理解为什么在设计时出现错误:
Class TMyDateTimePicker not found
为什么要查找 class? class 在实现细节中;它不是为流媒体发布的。流媒体系统是如何尝试创建它的!?所以我检查了 DFM:
object cfBeachBall: TContosoFrobber
Left = 445
Top = 25
Width = 101
Height = 22
...snip...
object TMyDateTimePicker
Left = 0
Top = 0
Width = 101
Height = 22
Date = 37306.581535243100000000
Time = 37306.581535243100000000
TabOrder = 0
TabStop = False
end
end
为什么 TInternalDateTimePicker
在 dfm 中结束:
- 属性 是 public,不是 发表的
如何阻止表单流系统在 dfm 中放置未发布的 属性?
更糟糕的是越野车IDE
它不仅有时包含一个 属性 不应该包含的内容。有时它包括 属性 它不应该 两次 :
object cfPlasticBag: TContosoFrobber
Left = 445
Top = 25
Width = 101
Height = 22
...snip...
object TMyDateTimePicker
Left = 0
Top = 0
Width = 101
Height = 22
Date = 37306.581535243100000000
Time = 37306.581535243100000000
TabOrder = 0
TabStop = False
end
object TMyDateTimePicker
Left = 0
Top = 0
Width = 101
Height = 22
Date = 37306.581535243100000000
Time = 37306.581535243100000000
TabOrder = 0
TabStop = False
end
end
- 如何阻止 dfm 包含未发布的属性?
- 如何阻止 dfm 包含它两次?
黑客解决方法
我知道可怕的黑客攻击:告诉 DFM 它不应该让任何业务知道的控件:
initialization
RegisterClass(TMyDateTimePicker);
finalization
UnRegisterClass(TMyDateTimePicker);
end.
现在 dfm 包含一个它不知道的控件。每次我保存表格时,它都会包含对不应该引用的内容的引用。最糟糕的是:我证实了它对 TMyDateTimePicker
的错误信念。
为什么DelphiXE6在重装前不这样做?也许我需要安装长期不受支持的 Delphi?
版本的最新更新已知错误?
问题是您将错误的 Owner
分配给了 TDateTimePicker
。您正在指定 TContosoFrobber
的所有者而不是 TContosoFrobber
本身:
constructor TContosoFrobber.Create(AOwner: TComponent);
begin
inherted Create(AOwner);
FMyControl := TMyDateTimePicker.Create(Self); // <-- not AOwner!
end;
或者:如 Jerry Doge 所述,您可以改用 nil
所有者。您只需手动 Free()
TDataTimePicker
:
type
TContosoFrobber = class(TCustomControl)
private
FMyDateTimePicker: TDateTimePicker;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
...
end;
constructor TContosoFrobber.Create(AOwner: TComponent);
begin
inherted Create(AOwner);
FMyControl := TMyDateTimePicker.Create(nil);
end;
destructor TContosoFrobber.Destroy;
begin
FMyControl.Free;
inherted Destroy;
end;