Как я могу видеть, кто инициировал действие в Delphi?

Когда событие TAction стреляет, "Отправитель" всегда является самим действием. Обычно это является самым полезным, но так или иначе возможно узнать, кто инициировал событие OnExecute действия?

Пример

Скажем, у Вас есть форма со следующим:

  • 2 кнопки, названные Button1 и Button2
  • 1 Касание называют actDoStuff

То же действие присвоено обеим кнопкам. Действительно ли возможно показать, какую кнопку я нажал?

Example.dfm

object Form1: TForm1
  object Button1: TButton
    Action = actDoStuff
  end
  object Button2: TButton
    Action = actDoStuff
    Left = 100
  end
  object actDoStuff: TAction
    Caption = 'Do Stuff'
    OnExecute = actDoStuffExecute
  end
end

Example.pas

unit Example;
interface
uses Windows, Classes, Forms, Dialogs, Controls, ActnList, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    actDoStuff: TAction;
    procedure actDoStuffExecute(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation    
{$R *.dfm}

procedure TForm1.actDoStuffExecute(Sender: TObject);
begin
  ShowMessage('Button X was clicked');
end;

end.

Единственное решение, которое я вижу в данный момент, не состоит в том, чтобы использовать свойство действия кнопок, но наличие eventhandler для каждой кнопки, и вызов actDoStuffExecute () оттуда, но такой игнорирует целую цель использовать действия во-первых.

Я не хочу иметь специализированное действие для каждого отдельного управления также. Примером выше является упрощенная версия проблемы, с которой я сталкиваюсь. У меня есть меню с переменным количеством пунктов меню (имена файлов), и каждый пункт меню в основном должен сделать то же самое, за исключением загрузки другого файла. Наличие действий для каждого пункта меню было бы немного глупо.

14
задан Didier Cabalé 25 July 2019 в 16:43
поделиться

5 ответов

Попробуйте использовать свойство ActionComponent :

Сохраняет клиентский компонент, который вызвал выполнение этого действия.

Используйте ActionComponent, чтобы определить, какой клиентский компонент вызвал выполнение этого действия. Например, изучите ActionComponent из обработчика события OnExecute если вам нужно знать, какое действие пользователя вызвало это действие.

Когда пользователь нажимает на элемент управления клиента, этот клиент устанавливает ActionComponent перед вызовом метода Execute действия. После выполнения действия действие сбрасывает ActionComponent на nil.

Например:

  ShowMessage( (Sender as TAction).ActionComponent.Name );

Используя это, я получаю "Button1" и "Button2" при нажатии на первую и вторую кнопку соответственно.

22
ответ дан 1 December 2019 в 07:38
поделиться

Знание того, какая кнопка запустила действие, противоречит точке использования действий - действие может быть инициировано нажатием кнопки, или щелчком меню, или любым количеством других действий пользователя. Действия существуют для унификации управления состоянием включения / выключения и обработки щелчков между кнопками и меню.

Если вы хотите знать, какая кнопка активировала действие, потому что вы хотите выполнить несколько иную операцию или «изменить» операцию по-другому, то, возможно, TAction не является правильным решением для того, что вы хотите сделать.

9
ответ дан 1 December 2019 в 07:38
поделиться

Вместо действий просто используйте событие click. Установите для всех кнопок один и тот же обработчик события. В идеале, НЕ названный в честь первой кнопки (вы можете переименовать его).

Вот код:

Procedure TMyForm.DestinationButtonClickHandlerThing(Sender: TObject); 
begin
  if Sender = Btn_ViewIt then
  begin
    // View It
  end
  else if Sender = Btn_FaxIt then
  begin
    // Fax It
  end
  else if Sender = Btn_ScrapIt then
  begin
    // Scrap It
  end
  else 
    ....   // error
   ...
end;
3
ответ дан 1 December 2019 в 07:38
поделиться

Хорошо, пока что я думаю, что нашел работоспособное решение ..

Я могу использовать одно и то же действие для всех элементов управления; Мне просто нужно переопределить их обработчик событий OnClick, и мне просто нужен один обработчик для всех из них.

Мне все еще интересно узнать, можно ли узнать, какой элемент управления вызвал действие, но для моего текущего приложения я использую решение, подобное приведенному ниже коду:

unit Example;

interface

uses
  Windows, Classes, Forms, Dialogs, Controls, ActnList, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    actDoStuff: TAction;
    procedure actDoStuffExecute(Sender: TObject);
    procedure ButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.actDoStuffExecute(Sender: TObject);
begin
  ShowMessage('Button '+TControl(Sender).Name +' was clicked')
end;

procedure TForm1.ButtonClick(Sender: TObject);
begin
  actDoStuffExecute(Sender)
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.OnClick := ButtonClick;
  Button2.OnClick := ButtonClick
end;

end.
0
ответ дан 1 December 2019 в 07:38
поделиться

установите тег кнопок как 1, 2, ... и т. Д., А затем:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.OnClick := ButtonClick;
  Button2.OnClick := ButtonClick;
end;

procedure TForm1.ButtonClick(Sender: TObject);
begin
  if Sender is TButton then
  begin
    Caption := 'Button: ' + IntToStr(TButton(Sender).Tag);
  end;  
end;
0
ответ дан 1 December 2019 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: