現在Windows7+VisualStudio+C#の環境でフォームを作成しています。
そこで、少し疑問に思ったことがあったので質問しました。
イベント処理についての質問なのですが、イベントハンドラーが1回でいいのに2回呼ばれたり、呼ばれて欲しくない場面で呼ばれてしまうという問題です。
例えば...
C#
1private void TextBox1_TextChanged(object sender, EventArgs e){ 2 if(TextBox1.Text.SubString(0, 6) != "http//"){ 3 TextBox1.Text = "http//"; //★ 4 } 5}
実際にこんなコードを書いているわけではないですが、こんな処理を書くと、★マークの行を実行した時に、余分にイベントが発生しますよね?
別にこの処理ならそこまで嫌なことはないのですが、重たい処理をしているような場合は2回実行されると少し不満な場合もあります。TextBox
に関してはModified
(だったかな?)を使えば回避できるようなことを聞いたことがあり、昔一度成功した記憶もありますが(現在は別の方法で回避しているので、ちょっと忘れかけです^^)。Modified
の役割も全然理解してません><
今回主に困っているのは、ListView
やDataGridView
などにあるSelectedIndexChanged
イベントです(もちろん他のイベントでも共通の悩みはあります)。
SelectedIndexChanged
を受け取るイベントハンドラーにSelectedIndex
の値をいじる処理を書いてしまうと処理が2回呼ばれてしまいます。また、フォーム開くときの初期化処理で値をセットする場合も、呼ばれて欲しくないタイミングで呼ばれてしまいます。
この問題を回避するために使っている現在の方法は...
C#
1public class EventSwitchForm : Form{ 2 private eventBool = true; 3 4 protected bool EventOn(){ 5 bool before = eventBool; 6 eventBool = true; 7 return before; 8 } 9 10 protected bool EventOff(){ 11 bool before = eventBool; 12 eventBool = false; 13 return before; 14 } 15}
のようなクラスを設計しておき...
C#
1private ListView1_SelectedIndexChanged(object sender, EventArgs e){ 2 if(!EventOff()) return; 3 4 try{ 5 //ここに処理を書く 6 }catch{throw;}finally{EventOn();} 7}
ほぼ全てのイベントハンドラーを上のように書いています。
この方法でも正しく動いているのでとても困っているわけではないのですが、なんとなく原始的ですし、もっとスマートな方法がないかと思っています。イベントハンドラー全てに書き方の規則を設けている時点で人的エラーの元ですし、これから集団で開発する時が来ると嫌われそうな気がしまして...
それとも、このように書かなければ正常に動かないような処理を書いている時点で、あまりよい書き方とは言えないのでしょうか?
このように書かなければ正常に動かない処理の一例としては、一つのデータを二通りの方法で入力させる場合などです。ListView
から選んでも良いし、TextBox
で直に入力しても良い。というような処理の場合...
0. TextBox
に値が入力される
TextBox
のイベントハンドラーが呼ばれるTextBox
の値に対応する値を検索し、ListView
の適切なアイテムを選択ListView
のイベントハンドラーが呼ばれるTextBox
に選択されたアイテムを入力- 2に戻る
1から始めても、4から始めても無限ループになってしまいます。この例の場合は、TextBox
やListView
に値をセットするときに前の値と同じかどうか確かめれば良いですが、実際にはもっと複雑な処理を書いているので、その方法が使えないこともあります。
プログラミングに関しては一応10年ほどやっていますが、ほぼ独学です(とはいえ覚えたのは14歳の頃なんで昔はかなり遊びでしたが><)。昔からMacのXcodeを使っていたので、VisualStudioでのWindowsフォーム作成については、あまり大掛かりなものは作ったことがありませんでした(今回が初めてぐらい)。なので結構基本的な分野を見落としている可能性もあります。
長文になってしまい申し訳ないですが、ご教授よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/08/11 07:59
2016/08/11 08:48
2016/08/11 10:00 編集