如何处理复合组件中子项的双击?
Posted
技术标签:
【中文标题】如何处理复合组件中子项的双击?【英文标题】:How to handle double click from childs in compound component? 【发布时间】:2017-04-02 03:22:48 【问题描述】:我创建了一个基于TCustomPanel
的新复合组件。
在它上面我有两个标签和一个图像,覆盖了所有的表面,看这个布局(下部不太重要):
我的问题是如何导出这些控件的双击功能?是否可以使用新控件的双击(事件)来管理其上的子控件?
【问题讨论】:
您是否希望所有控件同时响应 dblclick 或是否希望每个 ctrl 都有自己的 dblclick 事件处理程序,这不是很清楚。 【参考方案1】:我认为您应该使用以下方法来做到这一点:
-
将
OnDblClick
事件添加到复合组件。
在复合组件中添加一个名为FOnInternalDblClick
(名称不重要)的方法,与TNotifyEvent
兼容。
在FOnInternalDblClick
内部,执行复合组件的OnDblClick
。
在复合组件的构造函数中,将FOnInternalDblClick
分配给您要为其管理事件的每个组件的OnDblClick
事件。
示例代码:
TMyCompoundComponent = class(TCustomPanel)
protected
FOnDblClick : TNotifyEvent;
procedure FOnInternalDblClick(ASender : TObject);
public
constructor Create(AOwner : TComponent); override;
published
property OnDblClick : TNotifyEvent read FOnDblClick write FOnDblClick;
end;
constructor TMyCompoundComponent.Create(AOwner : TComponent);
begin
inherited;
//Lab1.OnDblClick := FOnInternalDblClick;
//Lab2.OnDblClick := FOnInternalDblClick;
//...
end;
procedure TMyCompoundComponent.FOnInternalDblClick(ASender : TObject);
begin
if(Assigned(FOnDblClick))
then FOnDblClick(ASender);
end;
注意:
在复合组件的OnDblClick
事件处理程序中,ASender
参数将是内部组件(Lab1
、Lab2
、Lab3
...)。如果您希望将复合组件本身作为ASender
参数接收,您可以通过传递Self
而不是ASender
来更改FOnInternalDblClick
方法:
procedure TMyCompoundComponent.FOnInternalDblClick(ASender : TObject);
begin
if(Assigned(FOnDblClick))
then FOnDblClick(Self);
end;
【讨论】:
Tnx 很多,正是我需要的。最好的问候。 你应该坚持经典的“if assignment()...”【参考方案2】:您的两个请求都是可能的。这取决于你想做什么。如果您希望能够在程序中为每个子项分别编写代码,则需要为组件创建三个额外的已发布属性并将它们映射到相应的子组件属性。像这样(仅显示一个子组件 - 对其他 2 个重复):
type
TMyPanelForm1 = class( TPanel )
private
fLabel1, fLabel2 : TLabel;
fImage : TImage;
procedure SetLabel1DblClick(const Value: TNotifyEvent);
function GetLabel1DblClick: TNotifyEvent;
public
constructor Create(AOwner: TComponent); override;
published
property OnLabel1DblClick : TNotifyEvent
read GetLabel1DblClick write SetLabel1DblClick;
end;
...
function TMyPanelForm1.GetLabel1DblClick: TNotifyEvent;
begin
Result := fLabel1.OnDblClick;
end;
procedure TMyPanelForm1.SetLabel1DblClick(const Value: TNotifyEvent);
begin
fLabel1.OnDblClick := Value;
end;
另一方面,如果你想让控件像一个统一的控件一样工作,所有三个子控件都“继承”主组件双击,你只需像这样降低分配:
TMyPanelForm2 = class( TPanel )
private
fLabel1, fLabel2 : TLabel;
fImage : TImage;
function GetOnDblClick: TNotifyEvent;
procedure SetOnDblClick(const Value: TNotifyEvent);
public
constructor Create(AOwner: TComponent); override;
published
property OnDblClick : TNotifyEvent
read GetOnDblClick write SetOnDblClick;
end;
...
function TMyPanelForm2.GetOnDblClick: TNotifyEvent;
begin
Result := inherited OnDblClick;
end;
procedure TMyPanelForm2.SetOnDblClick(const Value: TNotifyEvent);
begin
inherited OnDblClick := Value;
fLabel1.OnDblClick := Value;
fLabel2.OnDblClick := Value;
fImage.OnDblClick := Value;
end;
其他解决方案也是可能的。
【讨论】:
Tnx Dsm,实际上是第二种解决方案。我也尝试过这种方法,但我错过了一部分。以上是关于如何处理复合组件中子项的双击?的主要内容,如果未能解决你的问题,请参考以下文章