Как обрабатывать двойной щелчок от дочерних элементов в составном компоненте?

Я создал новый составной компонент на основе TCustomPanel. На нем у меня есть две этикетки и одно изображение, покрывающее всю поверхность, см. этот макет (нижняя часть менее важна):

Макет элемента управления

Мой вопрос: как экспортировать функциональность двойного щелчка любого из этих элементов управления? Можно ли использовать двойной щелчок (событие) нового элемента управления для управления дочерними элементами управления на нем?


person Laurent Saragosti    schedule 18.11.2016    source источник
comment
не очень ясно, хотите ли вы, чтобы все элементы управления отвечали на dblclick в унисон, или хотите, чтобы каждый ctrl имел свой собственный обработчик событий dblclick.   -  person Z80    schedule 22.07.2019


Ответы (2)


Я думаю, вы должны сделать это, используя следующий подход:

  1. Добавьте событие OnDblClick к составному компоненту.
  2. Добавьте метод с именем FOnInternalDblClick (название не важно), совместимый с TNotifyEvent в составной компонент.
  3. Внутри FOnInternalDblClick выполните OnDblClick составного компонента.
  4. В конструкторе составного компонента назначьте 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, вы можете изменить метод FOnInternalDblClick, передав Self вместо ASender:

procedure TMyCompoundComponent.FOnInternalDblClick(ASender : TObject);
begin
  if(Assigned(FOnDblClick))
  then FOnDblClick(Self);
end;
person Fabrizio    schedule 18.11.2016
comment
Tnx много, именно то, что мне нужно. С наилучшими пожеланиями. - person Laurent Saragosti; 18.11.2016
comment
Вы должны придерживаться классики, если назначено ()... - person Z80; 22.07.2019

Оба ваших запроса возможны. Это зависит от того, что вы хотите сделать. Если вы хотите иметь возможность писать свой код в программе отдельно для каждого подэлемента, вам нужно создать три дополнительных опубликованных свойства вашего компонента и сопоставить их с соответствующими свойствами подкомпонента. Вот так (показано только для одного подкомпонента - повторите для двух других):

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;

Возможны и другие решения.

person Dsm    schedule 18.11.2016
comment
Tnx Dsm, второе решение по сути. Я тоже пробовал этот подход, но мне не хватало части. - person Laurent Saragosti; 18.11.2016