DOBON.NET DOBON.NETプログラミング掲示板過去ログ

AcceptButtonが設定されているフォーム上でEnterキーを押しても反応しない

環境/言語:[環境(Windows 7)、使用言語(C#)、.NetFramework3.5]
分類:[.NET]

2011/03/03(Thu) 16:19:17 編集(投稿者)

System.Windows.Forms.FormのAcceptButtonプロパティにButtonが設定されている場合、
Enterキーを押下するとそのButtonのClickイベントが発生しますが、
これが発生しない場合があり困っています。

これを回避し、Clickイベントが発生するようにするにはどうしたら良いでしょか?


再現する条件は、
Form.AcceptButtonに設定されているボタンの、
直前のタブオーダーのコントロールがValidatingイベントを持っており、
そのコントロールでTabキーを押下してValidatingイベントを発生させ、
イベント内でCancelEventArgs.Cancelにtrueが一度でも設定された場合です。
この場合、対象のボタンにフォーカスが設定されるまでEnterキーでClickイベントが発生することはありません。

具体的な発生方法を示します。

前提条件
-------------->
FormにTextBox(txtInput)とButton(btnOk)を1つずつ配置します。

タブオーダー(TabIndex)をTextBox→Buttonの順に設定します。
(txtInput.TabIndex = 0; btnOk.TabIndex = 1;)

TextBoxのValidatingイベントに以下の条件文を記述します。

private void txtInput_Validating(object sender, CancelEventArgs e)
{
// 例えばですが、空ではないときイベントをキャンセルするという条件にします
if(txtInput.Text != "")
{
e.Cancel = true;
}
}

ButtonのClickイベントにはFormを閉じる処理を記述します。

private void btnOk_Click(object sender, EventArgs e)
{
this.Close();
}
<--------------

操作方法
-------------->
TextBoxにフォーカスを設定し、何も入力せずにEnterキーを押します。
この場合、Formが閉じます。(正常な動きです)

次に、TextBoxにフォーカスを設定し、何かを入力してTabキーを押します。※1
Validatingイベントのe.Cancelにtrueが設定されますので、Buttonにはフォーカは移動しません。
TextBoxに入力した値をすべて消します。(空にします)
そのままEnterキーを押します。
Formが閉じません。

※1でTabキーを押すのではなく、Buttonをマウスクリックするにした場合は、
Formが閉じます。
<--------------

ちなみに、CancelButtonプロパティでのEscキー押下時も同様の現象が発生します。

長文になってしまいましたが、
どうぞ、よろしくお願い致します。
こっちだと問題なく動きます。
ValidatingのCancel条件を満たしたままになっていないか確認してみてはどうでしょう?enterをKeyDownなどで処理してしまっているようなことはないでしょうか?
>こっちだと問題なく動きます。
私のところでも最小のプログラムを新規作成して試してみたところ、まきさんの書かれた状況が発生しました。
(WinXPProSP3で.NET FW3.5SP1にて。)

とりあえずe.Cancel = true;の際に(Control)sender.Focus();を書いておくと解消はできたものの、フォーカス遷移絡みで呼ばれている検証イベント処理内で自分へとは言えフォーカスの制御を無理に呼ぶので、プログラムによっては他に発生するイベント処理との兼ね合いで何か妙な不具合が出てしまうかもしれません。
2011/03/04(Fri) 11:09:58 編集(投稿者)

→shu様
ご返信ありがとうございます。

>ValidatingのCancel条件を満たしたままになっていないか確認してみてはどうでしょう?
Cancel条件というのが、
トピックNo.28276 の「前提条件」に示しましたサンプルで言うところの if(txtInput.Text != "") に該当するとしたら、
満たしたままにはなっていません。

「操作方法」に示しました通り、「TextBoxに入力した値をすべて消します。」というところで、
Cancel条件は満たさなくなっています。

>enterをKeyDownなどで処理してしまっているようなことはないでしょうか?
そのようなことはしておりません。

お手数ですが、試しにサンプル通りにやっていただくと発生すると思いますが、
いかがでしょうか?
発生しないとしたら…環境依存!?(;;)


→こど。様
ご返信ありがとうございます。

XPでも発生するんですね^^;
これってそもそも.NETの不具合なような気がしてきました…

こちらでも e.Cancel=true の直後にフォーカスを設定するようにしたら、
期待する動作になりました!

その回避方法は思いつきませんでした。
本当にありがとうございますm(__)m

以下の懸念点が残りますがこれで問題が起きないようでしたらこちらの方法を取らせていただきます。

>プログラムによっては他に発生するイベント処理との兼ね合いで何か妙な不具合が出てしまうかもしれません。
確かに、不安が残りますね。

しかし、Validatingイベントで e.Cancel=true の後にそのコントロールに対して、
フォーカスを受け取ったときに発生するEnterイベントが1回だけ呼ばれていまして、
e.Cancel=true の直後にフォーカスを設定するようにしてもEnterイベントは変わらず1回だけの呼び出しでした。

これは影響がないとみて良いのでしょうか?
いかが思われますか?

お手数をおかけして申し訳ありませんが、
もう少しだけお付き合い頂ければと思います。
■No28280に返信(まきさんの記事)

> お手数ですが、試しにサンプル通りにやっていただくと発生すると思いますが、
> いかがでしょうか?
> 発生しないとしたら…環境依存!?(;;)
一応試したつもりだったのですが、今日別のPCで試すと発生しました。
昨日試したのは[Win7HomePreSP1,C#2010EE,Frm4.0]、今日試したのは[Win7Ult x64 SP1,VS2010Pro C#,Frm4.0 Frm3.5]で今日のは4でも3.5でも駄目でした。
昨日の操作が悪かったのか環境が悪かったのか分かりませんが、状況が変わって
びっくりです。すいませんでした。
■No28281に返信(shuさんの記事)

早々のご返信ありがとうございます。

> 一応試したつもりだったのですが、今日別のPCで試すと発生しました。
> 昨日試したのは[Win7HomePreSP1,C#2010EE,Frm4.0]、今日試したのは[Win7Ult x64 SP1,VS2010Pro C#,Frm4.0 Frm3.5]で今日のは4でも3.5でも駄目でした。
> 昨日の操作が悪かったのか環境が悪かったのか分かりませんが、状況が変わって
> びっくりです。すいませんでした。
いえいえ、かえっていろいろな環境でお試しいただき感謝しております。
こど。様の

「とりあえずe.Cancel = true;の際に(Control)sender.Focus();を書いておくと解消 」という方法で解決とさせていただきます。

ありがとうございましたm(__)m
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板