How to handle double-click on children in a composite component?

I created a new composite component based on TCustomPanel . On it I have two labels and one image covering the entire surface, see this layout (the lower part is less important):

Control layout

My question is how to export the double-click function of any of these controls? Is it possible to use the double-click (event) of a new control to manage its child controls?

+6
source share
2 answers

I think you should do this using the following approach:

  1. Add the OnDblClick event to the composite component.
  2. Add the FOnInternalDblClick method (the name does not matter) compatible with TNotifyEvent in your composite component.
  3. Inside FOnInternalDblClick execute the FOnInternalDblClick composite component.
  4. In the composite component constructor, assign FOnInternalDblClick event of each component for which you want to control the event.

Code example:

 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; 

Remarks:

In the OnDblClick event ASender composite, the OnDblClick parameter will be an internal component ( Lab1 , Lab2 , Lab3 ...). If you prefer to get the composite component itself in ASender parameter, you can change the FOnInternalDblClick method by passing Self instead of ASender :

 procedure TMyCompoundComponent.FOnInternalDblClick(ASender : TObject); begin if(Assigned(FOnDblClick)) then FOnDblClick(Self); end; 
+4
source

Both of your requests are possible. It depends on what you want to do. If you want to write your code in the program separately for each sub-element, you need to create three additional published properties of your component and compare them with the corresponding properties of subcomponents. Like this (shown only for one subcomponent - repeat for another 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; 

On the other hand, if you want the control to act as a unified control, where all three subcontrols inherit the "main component" by double-clicking, you simply confuse the assignments as follows:

  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; 

Other solutions are possible.

+3
source

Source: https://habr.com/ru/post/1012444/


All Articles