如何处理复合组件中子项的双击?
How to handle double click from childs in compound component?
我基于 TCustomPanel
创建了一个新的复合组件。
在上面我有两个标签和一张图片,覆盖了所有的表面,看这个布局(下部不太重要):
我的问题是如何导出这些控件的双击功能?是否可以使用新控件的双击(事件)来管理其上的子控件?
我认为您应该使用以下方法来完成:
- 向复合组件添加一个
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;
你的两个要求都可以。这取决于你想做什么。如果您希望能够在程序中为每个子项单独编写代码,您需要为组件创建三个额外的已发布属性并将它们映射到相应的子组件属性。像这样(仅针对一个子组件显示 - 对其他 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;
另一方面,如果您希望控件像一个统一控件一样运行,其中所有三个子控件 'inherit' 主要组件双击,您只需像这样向下分配:
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;
其他解决方案也是可能的。
我基于 TCustomPanel
创建了一个新的复合组件。
在上面我有两个标签和一张图片,覆盖了所有的表面,看这个布局(下部不太重要):
我的问题是如何导出这些控件的双击功能?是否可以使用新控件的双击(事件)来管理其上的子控件?
我认为您应该使用以下方法来完成:
- 向复合组件添加一个
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;
你的两个要求都可以。这取决于你想做什么。如果您希望能够在程序中为每个子项单独编写代码,您需要为组件创建三个额外的已发布属性并将它们映射到相应的子组件属性。像这样(仅针对一个子组件显示 - 对其他 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;
另一方面,如果您希望控件像一个统一控件一样运行,其中所有三个子控件 'inherit' 主要组件双击,您只需像这样向下分配:
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;
其他解决方案也是可能的。