質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

3回答

2772閲覧

C# Windowsフォームのボタンイベント制御について

f_tonakai

総合スコア15

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2019/06/05 13:21

編集2022/01/12 10:55

前提・実現したいこと

C#でWindowsフォームの開発をしています。
今やりたいことは
1.フォーム上にボタンが2つ [button_A]と[button_B] がある。
2.[button_A]を押すと、処理が走る(例えば、DB接続やファイル書込)
3.(2)の処理中に[button_A]と[button_B]のクリックイイベントを動かないようにする。
ただし、ボタン非活性(enableプロパティ=true)は行わない。

発生している問題・エラーメッセージ

[button_A]の実行中に[button_A]や[button_B]をクリックすると、
[button_A]の処理後にイベントが実行されてしまう。(イベントがメモリ上に残ってしまう)

試したこと

イベント破棄をするために、
this.button1.Click += new System.EventHandler(this.button1_Click);
を実装したが、うまくいかない

// Form1.cs namespace TestSample { public partial class Form1 : Form { private int isProcessing; public Form1() { isProcessing = 0; InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if(isProcessing == 1) { return; } isProcessing = 1; this.button1.Click -= new System.EventHandler(this.button1_Click); this.button2.Click -= new System.EventHandler(this.button2_Click); // テキストに数字を出力(テスト用で簡易なロジック実装) DataOutPut dataOutPut = new DataOutPut("[start]", "[end]"); dataOutPut.OutPutFile(); isProcessing = 0; Application.DoEvents(); this.button1.Click += new System.EventHandler(this.button1_Click); this.button2.Click += new System.EventHandler(this.button2_Click); return; } private void button2_Click(object sender, EventArgs e) { this.Close(); return; } private void Form1_Closing(object sender, FormClosingEventArgs e) { if (isProcessing == 1) { Console.WriteLine("★ -- No Form1_Closing() -- ★"); e.Cancel = true; } } } }
// DataOutPut.cs namespace TestSample { class DataOutPut { private string startCode; private string endCode; public DataOutPut(string startCode, string endCode) { this.startCode = startCode; this.endCode = endCode; } // テキストファイルに出力 public int OutPutFile() { string filePath = @"C:\Users\fujiwarak\Desktop\work\"; string fileName = "test_"; string dt = (DateTime.Now).ToString("yyyyMMddHHmmss"); Encoding enc = Encoding.GetEncoding("Shift_JIS"); int index = 0; while (index < 3) { string filePathName = filePath + fileName + index.ToString() + dt + ".txt"; using (StreamWriter writer = new StreamWriter(filePathName, true)) { writer.WriteLine(startCode); int loop = 0; int number = 0; while (loop <= 10) { System.Threading.Thread.Sleep(1000); writer.WriteLine(number.ToString()); number++; loop++; } writer.WriteLine(endCode); } index++; } return 0; } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/06/05 22:18 編集

OutPutFile メソッドのループの中に Application.DoEvents を入れたらおそらく思う通りになると思いますが、Enabled でいいじゃないですか。何ですかその押せるのに押したらいけないという変な仕様?
f_tonakai

2019/06/08 08:45

OutPutFile メソッド側にいれてやってみます。 ありがとうございます。
Zuishin

2019/06/08 08:48

Enabled でいいじゃないですか。
guest

回答3

0

OutPutFileメソッドの終了時にtimerを立ち上げて
timer_tickイベントで
isProcessing = 0;
とすれば良いのではないでしょうか?
どれだけのイベントがメモリ上に残るのかわかりませんが、残ったイベントを逃がせると思います。

あと、isProcessingはboolでもいい気はしますが・・・。

投稿2019/06/05 23:54

k.matsuda

総合スコア293

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C#

1 this.button1.Click -= new System.EventHandler(this.button1_Click); 2 this.button2.Click -= new System.EventHandler(this.button2_Click); 3 4 this.button1.Click += new System.EventHandler(this.button1_Click); 5 this.button2.Click += new System.EventHandler(this.button2_Click);

ではなく

C#

1 this.button1.Click -= this.button1_Click; 2 this.button2.Click -= this.button2_Click; 3 4 this.button1.Click += this.button1_Click; 5 this.button2.Click += this.button2_Click;

とそれぞれ該当箇所書き換えてみてください。

投稿2019/06/05 17:47

gentaro

総合スコア8949

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/06/05 22:13

同じだと思います。後者は糖衣構文なので。
gentaro

2019/06/06 08:01

あ、そうか。ご指摘ありがとうございます。
guest

0

そのコードを提示しましょう
Aを押されてたらBをパスするという処理を書けば、動くことはありません。


this.button1.Click += new System.EventHandler(this.button1_Click);

+=というのはイベントを追加するだけです。


イベントが残る、んじゃなくて、メッセージがメッセージキューに溜まってるだけなんで、
フラグを解除する前にメッセージキューを処理してしまいましょう

C#

1 bool flg; 2 3 private void button3_Click(object sender, EventArgs e) 4 { 5 if (flg) return; 6 7 flg = true; // try finally するほうがいいでしょうな 8 Debug.WriteLine("button3"); 9 Thread.Sleep(2000); 10 Application.DoEvents(); // メッセージキューを処理 11 flg = false; 12 } 13 14 private void button4_Click(object sender, EventArgs e) 15 { 16 if (flg) return; 17 18 Debug.WriteLine("button4"); 19 Thread.Sleep(2000); 20 } 21

んで、フォームの☓をどうにかしたいなら、FormClosingイベントを処理すればいいです

投稿2019/06/05 13:24

編集2019/06/06 00:33
y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

f_tonakai

2019/06/05 14:07 編集

ありがとうございます 追加なんですが [button_A]も[画面右上の×ボタン]も動かないようにしたいです [button_A]の連打はできないようにしたいです
y_waiwai

2019/06/05 14:09

その処理中になんかフラグを立てるようにし、それらの処理をしようとするときにそのフラグを判断し、以降の処理をパスするようにコードを書けばいいです
f_tonakai

2019/06/08 08:47

ソースまでありがとうございます。 参考にさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問