Loadイベント中にほかのイベントを発生したくない

このQ&Aのポイント
  • VisualC# .netのフォーム表示時、コンストラクタの後にロードイベントでフォームの初期設定を行っています。しかし、このロードイベント内でコンボボックスの初期設定を行うと、コンボボックスのイベントが発生してしまいます。フラグを立てるかDebugger.IsAttachedを使用することで回避できます。
  • VisualC# .netのフォーム表示時、コンストラクタの後にロードイベントでフォームの初期設定を行っています。その際、コンボボックスの初期設定を行うとコンボボックスのイベントが発生してしまいます。この問題を解決するためには、フラグを立てるかDebugger.IsAttachedを使用する方法があります。
  • VisualC# .netのフォーム表示時、コンストラクタの後にロードイベントでフォームの初期設定を行っています。しかし、ロードイベント内でコンボボックスの初期設定を行うとコンボボックスのイベントが発生してしまいます。この問題を回避するためには、フラグを立てるかDebugger.IsAttachedを使用する方法があります。
回答を見る
  • ベストアンサー

Loadイベント中にほかのイベントを発生したくない

VisualC# .net です。 フォームを表示する場合に コンストラクタが呼ばれその後ロードイベントで フォームのコントロールの初期設定を行っています。 (この方法がまちがっている?) ロードイベント内でコンボボックスの初期設定を行うと コンボボックスのイベントが発生してしまいます。 以下参照にて このイベントでメッセージを表示しているのですが 初期設定では出てほしくありません。 そこで、 これを防ぐためには以下のようにフラグを立てるような 方法しかないのでしょうか? それともDebugger.IsAttached のようなものが 用意されているのでしょうか public bool iload = false;     (←仮フラグを追加) private void Form1_Load(object sender, EventArgs e) { iload = true;    (←仮フラグを登録) ComboBox1.SeletedIndex = 0; iload = false;   (←仮フラグを削除) } private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (iload) return;     (←仮フラグ登録時はなにもしない) MessageBox.Show("変更しました"); }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

SelectedItemChanged()で他にも処理をするようですし、フラグでいいんではないでしょうか。 Loadが終わったかどうかを判断するプロパティは無いと思います。 どうしてもプロパティやメソッドとして制御したいようなら、フォームにスーパークラスを作るとか、 アクセサにすればいいのでは。 個人的にはフラグはあまり使いたくありませんが。

MetalDragon
質問者

お礼

ありがとうございます。 やはり存在しないみたいですね とりあえず私も調べてそれらしいのをみつけました。 DesignModeっていうのがあるみたいですけど使えないみたいですね。 私もフラグは好きじゃないので質問をさせてもらったのですけど とりあえず今回はフラグを使用して対応しておきます。 スーパークラスは作れないです。作り方わからないです。 たぶん、サブクラス作って、内部でフラグを使用するぐらいしか思いつかないです。

その他の回答 (1)

回答No.1

Load中は、イベントを削除すればいいでしょう。 private void Form1_Load(object sender, EventArgs e) {  // イベントハンドラの削除  comboBox1.SelectedIndexChanged -= comboBox1_SelectedIndexChanged; // 色々な処理  // イベントハンドラの追加  comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged; } もしくは、デザイナ上でイベントハンドラを紐づけておかず(プログラムのみ記述しておく)、 イベントが完了後にイベントハンドラを追加すればいいです。 コンストラクタで当然InitializeComponent()が呼ばれるわけですが、 その中でイベントハンドラが設定されるのが問題でしょう。 どうしてもイベントハンドラ周りの制御をいじりたくないというのならば、 質問に記されているような制御を行うことになるでしょう。 また、どのような制御を行っているのかわかりませんが、初期化時にイベントが走行しても なんら影響のでないコードになっていれば、問題ないと思います。 逆に言うと、初期化によって選択されている値が変更されたにも関わらず、そのタイミング で処理すべき処理が行われないとすると、そちらの方が影響を及ぼしたりはしないでしょうか?

MetalDragon
質問者

補足

<<元々>> private void Form1_Load(object sender, EventArgs e) {  ComboBox1.SeletedIndex = 0; } private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e) {  Function(ComboBox1.Text);  MessageBox.Show("変更しました"); } 処理的には問題なく動作します。 ただ、同じ処理が数か所存在しているので 起動前にメッセージ文をユーザーがクリックして 何度もメッセージ消去するのはおかしいですよね。 ロード後にイベントを定義するという方法ですが、 これだと初期設定(ロード)時の処理が反映されなくなるのではないでしょうか? <<変更後:現実>> public bool iload = false; private void Form1_Load(object sender, EventArgs e) {  iload = true;  ComboBox1.SeletedIndex = 0;  iload = false; } private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e) {  Function(ComboBox1.Text);  if(iload == false) MessageBox.Show("変更しました"); } <<変更後:理想(Debugger.IsAttachedのようなEvent.Executeがあれば>> private void Form1_Load(object sender, EventArgs e) {  ComboBox1.SeletedIndex = 0; } private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e) {  Function(ComboBox1.Text);  if(!Event.Execute) MessageBox.Show("変更しました"); }

関連するQ&A

  • コンボボックスのイベントについて

    OS  :WindowsXP Pro SP1 開発環境:VisualStudio .NET 2003 開発言語:C# 開発形態:Windowsアプリケーション いつもこの場にお世話になっております。 今回もよろしくお願い致します。 現在、Windowsアプリケーションを作成しており、フォームにはコンボボックスとテキストが貼り付けてあります。コンボボックスは配列になっています。 using System.Windows.Forms; public class Form1 : System.Windows.Forms.Form { 省略   private ComboBox[] cmbArray = new ComboBox[3]; } private void Form_Load(object sender, System.EventArgs e) // フォームロード {   cmbArray[0] = comboBox1;   cmbArray[1] = comboBox2;   cmbArray[2] = comboBox3; } // イベントハンドラの登録 for( int i=0 ; i<3 ; i++) {   cmbArray[i].Validated += new System.EventHandler(ComboBoxClick); } private void ComboBoxClick(object sender, System.EventArgs e) {   MessageBox.Show(((ComboBox)sender).Text); } プログラムは上記のようになっています。 ここで質問なのですが、コンボボックス内のアイテムが変更されたらすぐに発生するイベントは何なのでしょうか?ここではClickイベントを使用していますが、コンボボックス内のアイテムを変更し、そのコンボボックスからカーソルが別のコントロールに移動して初めて発生します。 いろいろとイベントを試したのですが、どれもカーソルが移動する際に発生しているようなのです。 コンボボックス内のアイテムが変更されたらすぐに発生するイベントはあるのでしょうか?どなたかご存知の方がおりましたら、どうかご教授願います。

  • 別のフォームの値を初期値として設定するには?

    別のフォームの値を初期値として設定するには どうしたらよいでしょうか? private: System::Void Form2_Load(System::Object^ sender, System::EventArgs^ e) { this->comboBox1->Items = Form1.comboBox1.Items; }

  • コンボボックスの削除の仕方

    コンボボックスのリストの削除はどうしたらよいでしょうか。 private: System::Void comboBox1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) { index = comboBox1->SelectedIndex; cout << "index=" << index << "\n"; } private: System::Void button2_Click_1(System::Object^ sender, System::EventArgs^ e) { //comboBoxからデータ削除 comboBox1->Items->RemoveAt(index); このようなコードを書いてみましたがうまくいいきません。

  • イベントハンドラ関数について

    現在VC++/CLR 2005 でプログラミングをしています。 基本的な事柄かもしれませんが、質問させてください  以下の2つのボタンのイベントハンドラ関数があった場合 //ボタン1のイベントハンドラ関数 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) String^ str = textBox1->Text } //ボタン2のイベントハンドラ関数 private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { } ボタン2をクリックしたときの動作とボタン1の動作を同じにしたいと思っています。 その場合は private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) String^ str = textBox1->Text } //ボタン2のイベントハンドラ関数 private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { String^ str = textBox1->Text } のようにボタン2のイベントハンドラ関数をボタン1と同じように書けばいいのですが イベントハンドラ関数の処理が膨大になった場合を考えて省略する 書き方は無いのでしょうか?(以下の場合ですとエラーが起こってしまいます。) private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { button1_Click(); } 宜しくお願いします

  • c# イベントハンドラ 統一

    trackBarを複数配置しているのですが、そのtrackBarごとに private void trackBar1_Scroll(object sender, EventArgs e) { previewcolor(this.trackBar1.Value,'赤'); } private void trackBar2_Scroll(object sender, EventArgs e) { previewcolor(this.trackBar1.Value, '青'); } private void trackBar3_Scroll(object sender, EventArgs e) { previewcolor(this.trackBar1.Value, '緑'); } private void trackBar4_Scroll(object sender, EventArgs e) { previewcolor(this.trackBar1.Value, '透'); } こんな風に別々に記述する形になって非常にスッキリしないです。 これをジェネリクス?やデリゲート?などを使ってすっきりできないのでしょうか? visual stdio c# 2008を使ってます。 宜しくお願いします。

  • イベント発生について

    お世話になります。 .NET C#で開発をしております初心者です。 テキストボックスに数字を入力したら、その値をメッセージボックスで ユーザーに確認を促したいのですが、そのイベント発生タイミングを どうしたらいいのか考えています。 現在は下記の様にしています。 まず、TextChangeイベントで、変数に代入してから、Leaveイベントでメッセージボックス を表示させています。 本当は、Leaveイベントでなく、その場でメッセージボックスを表示させたいのですが、 でも、TextChangeイベントだけでは、例えば二桁以上の数字を入力しようとしていた場合、 一桁数字を打ち込む度に、TextChangeイベントが発生してしまい、その度にメッセージボックスが 表示されてしまうので、仕方なくLeaveイベントも使っています。 何か良い方法ってありますでしょうか。 どなたかご親切な方、ご教授頂きたく宜しくお願い致します。                           記 private void textBox1_TextChanged(object sender,EventArgs e) { if(textBox1.Text != "-") { if(textBox1.Text != "") { suuryou = int.Parse(textBox1.Text);   } } } private void textBox1_Leave(object sender,EventArgs e) { if(textBox1.Text != "") { MessageBox.Show(suuryou,"", MessageBoxButtons.OK, MessageBoxIcon.Information); } }

  • Sleep(0)について

    VS2010C++でWindowsフォームアプリケーションをつくろうとしています。 ループさせたいイベント(button1)中に、button2のイベントを行いたいのでSleep(0)を使って以下のようにしました。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { while(1){ Sleep(0); // ループさせたいイベント ・・・・・・・・・・・・・・・・・・・・ } } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {    ・・・・・・・・・・・・・・・・・・・・ } アプリケーション起動後button1をクリックすると、Sleep(0)が無いときと同じようにボタンを受け付けなくなります。 Sleep(0)の使い方が間違っているのでしょうか。

  • ComboBoxについて

    ComboBoxのアイテムリストからアイテムを選んだら 選んだアイテムに対応した別の文字列 をComboboxに表示したいと思います。 動き的には Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  ComboBox1.Text = ""  ComboBox1.Items.Add("000")  ComboBox1.Items.Add("001")  ComboBox2.Text = ""  ComboBox2.Items.Add("0個目")  ComboBox2.Items.Add("1個目")  ComboBox2.Visible = False End Sub Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged  Select Case ComboBox1.SelectedIndex   Case 0    ComboBox1.Visible = False    ComboBox2.Visible = True    ComboBox2.SelectedIndex = 0   Case 1    ComboBox1.Visible = False    ComboBox2.Visible = True    ComboBox2.SelectedIndex = 1  End Select End Sub Private Sub ComboBox2_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox2.GotFocus  ComboBox1.Visible = True  ComboBox1.DroppedDown = True  ComboBox2.Visible = False End Sub こんな感じで、ComboBoxを二つ使えば実現できるのですが一つだけでも実現できる方法が ありましたら、教えてくださいませ。

  • .netframeworkで作成したフォーム1のイベントで、フォーム2を表示させたいのですが…

    ものすごく説明しにくいのですが、以下のプログラムを実行すると 「Form2識別子がクラス名でも名前空間名でもありません。」 と、エラーが表示されてしまいます。 クラスが違うからなのでしょうか?何か方法は無いのでしょうか・・・。 何か分かることがあったらよろしくお願いいたしますm(_ _)m private: System::Void Form1_Load(System::Object * sender, System::EventArgs * e) {//フォームロード Form2::Show(); }

  • C# 簡単なシューティング 自機移動について

    かなりの初心者で困っています。 簡単なシューティングを作ろうとおもっています。 使用ソフトはVisualC#2005です。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //自機(右移動) private void button3_Click(object sender, EventArgs e) { if (timer1.Enabled == false) { timer2.Enabled = false; timer1.Enabled = true; } else { timer1.Enabled = false; timer3.Enabled = false; timer4.Enabled = false; } } private void timer1_Tick(object sender, EventArgs e) { pictureBox1.Left = pictureBox1.Left + 2; } //自機(左) private void button4_Click(object sender, EventArgs e) { if (timer2.Enabled == false) { timer1.Enabled = false; timer2.Enabled = true; } else { timer2.Enabled = false; timer3.Enabled = false; timer4.Enabled = false; } } private void timer2_Tick(object sender, EventArgs e) { pictureBox1.Left = pictureBox1.Left - 2; } //自機(上) private void button1_Click(object sender, EventArgs e) { if (timer3.Enabled == false) { timer4.Enabled = false; timer3.Enabled = true; } else { timer1.Enabled = false; timer2.Enabled = false; timer3.Enabled = false; } } private void timer3_Tick(object sender, EventArgs e) { pictureBox1.Top = pictureBox1.Top - 2; } //自機(下) private void button2_Click(object sender, EventArgs e) { if (timer4.Enabled == false) { timer3.Enabled = false; timer4.Enabled = true; } else { timer1.Enabled = false; timer2.Enabled = false; timer4.Enabled = false; } } private void timer4_Tick(object sender, EventArgs e) { pictureBox1.Top = pictureBox1.Top + 2; } } } 自機は画像(PictureBox)でボタンによって上下左右に移動します。 FormのSizeは800,630です。 自機の移動がボタンなのでキー入力によって操作できるようにしたいのですが、 それと、自機の移動範囲を画面からでないようにしたいです。 あまりC#を理解できてない上でつくったのでおかしな点が多々あると思います。 教えていただける方がいると助かります。