10 delphi
我一直在编写一些自己的自定义组件,其中一些只是从其他组件派生而来,如TCustomButton,TCustomListBox等.
让我们说我有TMyButton = class(TCustomButton)
,这是在一个名为MyButton的单元中,我已经将这个组件注册并打包并安装到IDE中.
现在我将创建一个新的空项目并将TMyButton拖放到表单中.当我编译项目时,它会自动将这些单元添加到接口部分:
.., StdCtrls, MyButton;
Run Code Online (Sandbox Code Playgroud)
我当然希望添加MyButton,但希望StdCtrls不是.
这并不是那么糟糕,但是我的其他一些组件更糟糕,例如派生TCustomActionMainMenuBar
自我,当我将其添加到我的表单并编译时,我将添加以下额外单元:
.., ToolWin, ActnMan, ActnCtrls, ActnMenus, MyMenu;
Run Code Online (Sandbox Code Playgroud)
我想创建自己的组件的原因之一是为了防止在界面部分添加了如此多的单元名称,我希望自己绘画并更改默认属性等.
当我将3或4个组件添加到表单时,会自动添加额外的6-10个单元名称,我不希望这种情况发生.
所以我的问题 - 是否可以阻止IDE自动将单元名称添加到接口部分?
事实上,我已经在我自己的组件源的实际使用界面中有"不需要的"单元名称,我认为这已经足够了.我的组件知道他们需要哪些单元,那么为什么表单的源文件必须知道/被允许包含这些名称呢?
我只是想MyButton, MyMenu;
自动添加,而不是所有其他常见的单位名称与它们一起添加.
Rem*_*eau 10
有可能您的组件派生自其他具有已注册TSelectionEditor
实现的实现(请参阅参考资料RegisterSelectionEditor()
),这些实现将覆盖虚拟TSelectionEditor.RequiresUnits()
方法以将所需单元插入uses
子句中.执行此操作的一个原因是,这些组件是否定义依赖于其他单元中的类型的属性/事件.
TL;博士;
不可能阻止添加这些单元,你不应该再关心它了.
我的组件知道他们需要哪些单元,那么为什么表单的源文件也必须知道名称呢?
你是对是错.当然,如果代码仅限于创建组件,那么只需要声明该组件的单元.运行时和设计时.但是当代码开发出来,并且您希望实现需要来自祖先单元的类型的事件处理程序时,那么您的代码需要uses子句中的那些单元.运行时和设计时.
示例:在表单上TDBGrid
从单元中删除a时DBGrids
,也会Grids
添加单元,因为在祖先单元中声明了已发布事件的State
参数类型.在设计器中双击该事件会导致添加以下处理程序:TGridDrawState
OnDrawDataCell
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
end;
Run Code Online (Sandbox Code Playgroud)
现在,由于存在TGridDrawState
,这个源文件需要知道该Grids
单元.
结论:用于次要开发的单元可能太多,但总是有足够的单元用于实现所有已发布的事件.
我做了一些关于它是如何工作的研究.我已经赞成了雷米的答案,因为没有它我就不会想到这样做,但他实际上并不完全正确.
考虑以下示例单位:
unit AwLabel;
interface
uses
Classes, StdCtrls;
type
TAwLabelStyle = (bsWide, bsTall);
TAwLabel = class(TLabel)
private
FStyle: TAwLabelStyle;
published
property Style: TAwLabelStyle read FStyle write FStyle default bsWide;
end;
implementation
end.
Run Code Online (Sandbox Code Playgroud)
unit AwLabelEx;
interface
uses
Classes, AwLabel;
type
TAwLabelEx = class(TAwLabel);
implementation
end.
Run Code Online (Sandbox Code Playgroud)
unit AwReg;
interface
uses
AwLabel, AwLabelEx;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TAwLabel, TAwLabelEx]);
end;
Run Code Online (Sandbox Code Playgroud)
现在,您将一个TAwLabelEx
组件放在表单上,单位AwLabel
并AwLabelEx
添加,这会自动发生.不需要特别的参与.该类型AwLabel
需要该单元TAwLabelStyle
.请注意,在这种情况下,它与事件无关.剩下的唯一参数是该类型在组件定义的已发布部分中使用.
如何ISelectionEditor.RequiresUnits
为雷米说?
考虑我们搬到TAwLabelStyle
另一个单位:
unit AwTypes;
interface
type
TAwLabelStyle = (bsWide, bsTall);
implementation
end.
Run Code Online (Sandbox Code Playgroud)
现在,当您在表单上删除一个TAwLabel
或TAwLabelEx
组件时,不会添加该AwTypes
单元.引用上一个链接:
注意:事件可能会使用一个类型,其参数之一既不在类单元中也不在其任何祖先单元中.在这种情况下,应该注册实现RequiresUnits的选择编辑器,并将其用于声明事件所需类型的每个单元.
那么,让我们注册一个选择编辑器:
unit AwReg;
interface
uses
Classes, AwTypes, AwLabel, AwLabelEx, DesignIntf, DesignEditors;
type
TAwLabelSelectionEditor = class(TSelectionEditor)
public
procedure RequiresUnits(Proc: TGetStrProc); override;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TAwLabel, TAwLabelEx]);
RegisterSelectionEditor(TAwLabel, TAwLabelSelectionEditor);
end;
{ TAwLabelSelectionEditor }
procedure TAwLabelSelectionEditor.RequiresUnits(Proc: TGetStrProc);
begin
Proc('AwTypes');
end;
end.
Run Code Online (Sandbox Code Playgroud)
现在删除表单上的一个TAwLabel
或TAwLabelEx
组件会导致将该AwTypes
单元添加到uses子句中;