我创建了一个我想要注册为组件的新框架.我已经从这个问题中了解了RegisterSprigType ,所以它给我带来了一些麻烦.
RegisterSprigType正确地阻止设计者选择,意外移动或删除框架内的控件,但只能直接.里面的控件仍然接受要删除的控件.
在我的情况下,我的框架内有面板.我可以在所述面板上按下按钮.如果我删除按钮,那么父选择(恰好是面板),然后我可以删除面板.
我尝试从框架的ControlStyle中删除csAcceptsControls.它确实阻止了控件直接放在框架上,但是面板内部仍然接受了控件.
所以,我最终在"Loaded"过程中从我的框架中包含的所有控件中删除了csAcceptsControls.
如果我的框架是动态创建控件以响应属性更改,我认为我还需要覆盖Notification过程以从任何添加的控件中去除csAcceptsControls.
所以,我的问题是,是否有更好的方法来实现相同的结果(防止设计者在注册为组件的框架内添加控件).一个"注册"告诉设计者可能忽略框架类及其子框架作为容器?
如果这种方法已经是最优的,我是否会错过任何一项?
用这种方法我应该注意哪些"陷阱"?(任何副作用?设计和运行时.)
我深入研究,但没有很好的解决方案来解决您的问题,因为所有方法都在 Frame 上下文中工作,而不是在其子组件中工作,例如 DesignWndProc、WM_NCHITTEST ...
但我有解决方案(不太好),请看下面,但我不知道它是否比您删除 csAcceptsControls 的解决方案更好。
您可以在设计时仅创建Panel(透明)并仅从中删除csAcceptsControls。在调整框架大小时,您可以设置此面板的宽度和高度以吃掉整个框架。但是您必须将所有控件放在某个顶级面板(父级是 Frame)中并对齐 alClient,并且每个控件都将位于其上。然后,您创建设计时间面板(父级是框架),它将成为框架上的第二个顶级面板。创建后您只能将其置于前面一次。这消除了需要更改创建新控件的每个属性的需要。
像这样的结构 Frame{PanelTopLevel{任何其他控件}}{DesignPanel}:
object FrameTestDisableFrame: TFrameTestDisableFrame
object PanelTopLevel: TPanel
object Panel1: TPanel
Left = 96
Top = 56
Width = 201
Height = 105
Caption = 'Panel1'
TabOrder = 0
object Button1: TButton
Left = 48
Top = 24
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
end
end
end
Run Code Online (Sandbox Code Playgroud)
设计面板代码
TDesignPanel = class(TWinControl)
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
public
constructor Create(AOwner: TComponent); override;
end;
Run Code Online (Sandbox Code Playgroud)
执行
{ 设计面板 }
constructor TDesignPanel.Create(AOwner: TComponent);
begin
inherited;
ControlStyle:= ControlStyle - [csAcceptsControls];
Color:= clBackground;
end;
procedure TDesignPanel.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle:= Params.ExStyle or WS_EX_TRANSPARENT;
end;
procedure TDesignPanel.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
Message.Result:= 1;
end;
Run Code Online (Sandbox Code Playgroud)
并在你的框架中
private
DesignPanel: TDesignPanel;
Run Code Online (Sandbox Code Playgroud)
...
constructor TFrameTestDisableFrame.Create(AOwner: TComponent);
begin
inherited;
ControlStyle:= ControlStyle - [csAcceptsControls];
if csDesigning in ComponentState then
begin
DesignPanel:= TDesignPanel.Create(Self);
DesignPanel.Parent:= Self;
DesignPanel.BringToFront;
end;
end;
procedure TFrameTestDisableFrame.Resize;
begin
inherited;
DesignPanel.BringToFront;
DesignPanel.SetBounds(0, 0, Width, Height);
end;
Run Code Online (Sandbox Code Playgroud)
我测试了这个并且工作正常
暗示
就我而言,我的框架内有面板。我可以在所述面板上放置一个按钮。如果我删除该按钮,则会选择父级(恰好是面板),然后我可以删除该面板。
在德尔福西雅图,当我删除此类按钮时,将选择整个框架而不是父面板。
| 归档时间: |
|
| 查看次数: |
820 次 |
| 最近记录: |