ほかのクラスのボタンなどのイベントを発生させるときのSenderの扱い

解決


すー  2010-12-10 02:13:27  No: 39688

タイトルについて質問です。

Form1のBtnOn1Click処理でForm2のBtnONボタン処理を呼び出すとき、

Procedure Form1.BtnOnClick1(Sender:TObject);
begin
 Form2.BtnON.OnClick(Sender);
end;
とすれば問題なく処理できますが、いまいちOnClick(Sender);
のSenderを引数に渡しても大丈夫なのか自信がありません。

こういった場合どのようにするのがベストなのか?アドバイスください。

よろしくお願いします。


tor  2010-12-10 02:27:30  No: 39689

そのイベントを処理する人がSenderを利用していれば問題になりますし、
使っていなければ問題になりません。
Senderを利用する場合、そのイベントを発行したコンポーネントが入っていることを期待するのが普通なので
Form2.BtnON.OnClick(Form2.BtnON); みたいにした方がどちらかと言えば安全な可能性が高いかなーと考えられないこともありません。

普通はそんなことを考えず Form2.BtnON.Click; でいいです。


通りすがり  2010-12-11 01:03:33  No: 39690

Form2.BtnON.OnClick の値がころころ変わる場合は別ですが
Form2.BtnON.OnClick のイベントハンドラがスコープ内(アクセスできる位置)にあるなら
直接呼んだほうがいいのでは。
OnClickに限らず、イベントは、Form2.BtnON.OnClickは、Form2.BtnONのためのものであって欲しい場合のほうが多いと思いますので。

procedure Form2.BtnONClick(Sender);
begin
    MessageDlg('test',mtInformation,[mbOK],0);   
end;

みたいなイベントハンドラがForm2にあるとして

Procedure Form1.BtnOnClick1(Sender:TObject);
begin
   Form2.BtnONClick(Sender);
end;

のように直接メソッド(イベントハンドラ)を呼べるなら、そうしたほうがよいと思います。

なお、Form2.BtnOn.OnClick()を使ってイベントハンドラを呼び出すには、アサインされてるかどうか確認するようにしたほうが、よいと思う。

if Assigned(Form2.BtnON.OnClick) then
  Form2.BtnON.OnClick(Form2.BtnON)

Sender が重要になる場合というのは、イベントハンドラ内でSenderを使う場合だけなので、nil で呼び出しても問題ありません。
   Form2.BtnONClick(nil);

むしろ、直に呼び出す場合は、特に意図してSenderを伝えたい場合以外は nil にするべき。
そうすれば、ハンドルする側で、直接呼ばれたものなのか、イベントによって呼ばれたものなのかが判断できます。

イベントハンドラ内では
procedure TForm2.BtnONClick(Sender:TObject);
begin
 if Assigned(Sender) then
 begin
  さらに
  if Sender is TButton then
  begin
     TButton(Sender).Caption:='OK';
  end;
  あるいは
  if Sender=Form1.Button1 then
  begin
     Form1.Button1.Caption:='OK';
  end;
  場合によっては
  if Sender is TList then
  begin
    TList(Sender).Add()
  end;
 end;
end;
のような処理例が考えられるので、その辺を踏まえて Sender を渡すかどうか考えるようにすれば、よいと思います

この場合TNotifyEventでパラメータはSenderのみですが、それ以外の場合もパラメータリストさえあえば
イベントハンドラを1つにまとめることもできるわけで、まあいろいろ、どーするのが効率がよいか
可読性が高いかとか、処理速度を優先するか、リソース効率を高めるかで、その都度考えるように
なるかと思います。

ということで、特に決まったやり方というのは無く、その都度考えなければならないということです。


すー  2010-12-11 01:26:55  No: 39691

回答ありがとうございます。

よくわかりました。

呼び出し側でどのような処理をするかによって使い分けることですね。

ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加