QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

C# イベントを呼び出すには

以下にはテキストボックス1のTextChangedイベントがあります。
このイベントを関数から呼び出す場合
textBox1_TextChanged();
で()内に引数を指定して呼び出すのだと思いますが
object sender   にはtextBox1をオブジェクト型にキャストしたものを指定し?
System.EventArgs e にはなにを指定してあげればイベントを呼び出せるのでしょうか?

ご指導のほどよろしくお願いします。

///
/// textBox1の内容が変更された場合
///
/// イベントのソース
/// イベントデータの格納
private void textBox1_TextChanged(object sender, System.EventArgs e)
{

}

質問者:Dr’アライ

回答

TextChangedイベントを起動することと、textBox1_TextChanged()の関係が分からないのですが。
textBox1_TextChanged()内からTextChangedイベントを起こす?
それともtextBox1_TextChanged()はテキストボックスのTextChangedイベントに結び付けられたメソッドですか?

使ったことはありませんが、TextChangedイベントはOnTextChanged()で起動できるみたいですね。
EventArgs型の引数はおそらくEventArgs.Emptyで良いんだと思います。「変わった」ことを表すだけなので、座標など追加の情報はないですからね。

投稿者:一郎

編集 履歴 (0)

一郎さん、迅速な対応ありがとうございます。

質問したかった内容は後者の
>それともtextBox1_TextChanged()はテキストボックスのTextChangedイベントに結び付>けられたメソッドですか?
です。

回答頂いたとうり、EventArgs.Emptyを指定しイベントの実行が出来ました。
また、回答頂いた内容で勉強し、
object senderもイベント内で使用していなかったのでNullを指定してみました。

textBox1_TextChanged(Null,EventArgs.Empty);

非常に助かりました、どうもありがとうございました。

投稿者:Dr’アライ

編集 履歴 (0)

イベントの処理を別のメソッドから行いたいということであるなら、
その処理を行うメソッドを用意して、
それを呼ぶようにした方がいいのではないでしょうか?

投稿者:架空兎

編集 履歴 (0)

object senderもイベント内で使用していなかったのでNullを指定してみました。

いろいろと気になりますが、とりあえずこれはやめた方がいいです。
せめて sender にはイベントもとのコントロールを渡してやってください。
いつ、イベントの sender を使う必要が出てくるか分かりません。

まあ、その前に、イベントメソッドの割付が変わったらとかありますが。

投稿者:なちゃ

編集 履歴 (0)

貴重なご意見ありがとうございます。

>イベントの処理を別のメソッドから行いたいということであるなら、
>その処理を行うメソッドを用意して、
>それを呼ぶようにした方がいいのではないでしょうか?

ある既存のイベントの処理を、メソッドからもイベントと同様の処理を行いたい
と思い、単純にステップ数も増えなく、わかり易いと思いイベントを呼び出すと
いう方法をとったのですが。
このような場合イベントを呼び出すという方法は、良くないのでしょうか?
ご教授の程宜しくお願いします。

投稿者:Dr’アライ

編集 履歴 (0)

なちゃさん、ご教授ありがとうございます。

>いつ、イベントの sender を使う必要が出てくるか分かりません。

おっしゃる通りです、Nullを指定したのは少し安易でした。
今後、バグの原因になる可能性もあるので元のコントロールを指定します。

投稿者:Dr’アライ

編集 履歴 (0)

ああ、すいません。
内容がうまく読み取れていませんでした。

textBox1のTextChangedイベントに結びつけらている、EventHandler型の(正しい表現ではありませんが)引数と返り値を持つメソッドtextBox1_TextChanged()を通常のメソッド呼び出しのようにコードから呼び出したい
ということですね?

第二引数はEventArgs.Emptyで良いようです。
第一引数にはtextBox1を渡してはいけません
なぜってその呼び出しはtextBox1(のイベント)から呼び出されたわけではないからです。
textBox1_TextChanged()の第一引数が「メソッド実行の原因となったオブジェクト」「イベントのソース」という意味ならtextBox1はソースとは言えません。
ではtextBox1_TextChanged()を呼び出したメソッドをメンバとして持つオブジェクト(例えばフォーム)を渡すのか、というとそれもおかしな気がします。

一番美しい解決策は架空兎さんのおっしゃった方法だと私は思います。

メソッドそれぞれに、短い文で役割を付けてみてください。
「複数の数値の中から最大値を見つける」
「画面が表示された時の処理を行う」
「のに接続する」
「データベースからデータを取得し一覧を画面に表示する」
大きい視点、小さい視点といくつか書いてみましたが、メソッドは抽象化されているべきです。

textBox1_TextChanged()の役割は何ですか?
それはtextBox1.TextChangedが起動したときの処理を行うことです。
例えば
「textBox1のテキストが書き換えられたときには、textBox1のテキストを商品コードとしてデータベースからデータを取得し、商品詳細表示部を再描画する」
というプログラムだった場合、データベースからデータを取ってくる処理や商品詳細表示部を再描画する処理はtextBox1_TextChanged()には直接書きません。
テキストが書き換えられたときは商品詳細表示部を再描画しますが、商品詳細表示部を再描画するときはテキストが書き換えられたときとは限らないからです。
直接書くから「button1を押した時も商品詳細表示部を再描画したい」となった時にtextBox1_TextChanged()を呼びたくなってしまうのです。

・・・書き込みめっちゃ長っ!

投稿者:一郎

編集 履歴 (0)

Dr’アライさんの書き込み (2004-01-15 12:20) より:

ある既存のイベントの処理を、メソッドからもイベントと同様の処理を行いたい

と思い、単純にステップ数も増えなく、わかり易いと思いイベントを呼び出すと

いう方法をとったのですが。

このような場合イベントを呼び出すという方法は、良くないのでしょうか?

#以下すべて私の見解なのですが。。。^^;

特に禁止されているわけではないのですが、
イベントハンドラは通常、それを登録したオブジェクトのイベントに対して
何らかの処理を行うことが目的のメソッドなので、
それ以外の目的でそのメソッドを実行するのはあまりいいとは言えないと思います。

また、メンテナンス面でも、例えばイベントとして実行された場合と
直接呼ばれた場合とで処理を分けることが必要となった場合、
メソッドの引数を増やすわけにもいかず、
また、引数に判断材料を設定したり、フィールドを使ったりするのも
かなり無理があると思います。

だとしたら、その処理を行うメソッドを用意しておけば引数を増やすのも
戻り値を返すのも自由で、さらにメソッドに分かりやすい名前をつけてあげれば
それを見ただけで簡単にその処理の概要が理解しやすくなると思います。

#余談
#イベントハンドラの名前は通常、どのオブジェクトの何のイベントで
#実行されるのか理解しやすい名前をつける。
#VS.NET だと"オブジェクト名_イベント名"。

投稿者:架空兎

編集 履歴 (0)

一郎さん、架空兎さんご指導ありがとうございます。
私には、抽象化という考えが非常に浅かったようで、お二方のスレッドを
見て非常に感銘いたしました。
そもそも、textBox1_TextChanged()を呼び出さなくてはならない作りを見直し
たいと思います。
この考えは今後の作業に非常に役に立つと思います。ありがとうございました。

投稿者:Dr’アライ

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。