- PR -

MDIの子フォームでEnterキーが拾えず、ボタンクリックが動作する時がある(C#)

1
投稿者投稿内容
こま
会議室デビュー日: 2004/03/18
投稿数: 5
投稿日時: 2004-04-13 18:36
皆さんこんにちは。

過去ログを検索したのですが解決できなかったので、投稿させていただきます。
C#でMDIのアプリケーションを開発しています。
TextBoxでEnterキーのイベントを取得したいのですが、KeyDownのイベントが
拾えたり、拾えなかったりしてしまいます。
拾えないときは、そのフォーム内にあるいずれかのボタンのクリックイベントが
動作してしまいます。

条件は、
 MDIで子フォームが2つ以上あり、
 各フォームにボタン、テキストボックス(その他コントロール)がついている

通常はTextBoxのKeyDownイベントが拾えるのですが、2つの子フォーム内にある
ボタンをクリックしたりしていると、カーソルはTextBoxにあるのですが、TextBoxでKeyDownが拾えなくなり、そのフォーム内にあるボタンクリックのイベントが起きてしまいます。
(発生方法がいまいちはっきりしません)

フォームのプロパティで、Accept、Cancelボタンの設定は「なし」にしてあります。

TextBoxにカーソルがある状態でEnterを押した場合に、ボタンのクリックイベントを発生させたくないのです。
(ボタンにフォーカスがあるときは通常通りEnterでクリックイベントが発生したい)


どなたかご教授ねがいます。

こま
会議室デビュー日: 2004/03/18
投稿数: 5
投稿日時: 2004-04-13 21:01
ちょっと長いのですが、以下サンプル的なソースです。
KeyDownとボタンクリックのイベントでステータスバーにコメントが表示されます。
各子FORMでテキストボックスをクリックしてEnterをクリックすると、
ボタンクリックが動いてしまう時があります。

namespace FocusText
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.StatusBar statusBar1;
public Form1()
{
InitializeComponent();
Form2 fm2_1 = new Form2();
fm2_1.MdiParent = this;
fm2_1.Dock = DockStyle.Left;
fm2_1.Text = "子FROM 1";
fm2_1.Show();
Form2 fm2_2 = new Form2();
fm2_2.MdiParent = this;
fm2_2.Dock = DockStyle.Right;
fm2_2.Text = "子FROM 2";
fm2_2.Show();
}
private void InitializeComponent()
{
this.statusBar1 = new System.Windows.Forms.StatusBar();
this.SuspendLayout();
// statusBar1
this.statusBar1.Location = new System.Drawing.Point(0, 247);
this.statusBar1.Name = "statusBar1";
this.statusBar1.Size = new System.Drawing.Size(488, 22);
// Form1
this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
this.ClientSize = new System.Drawing.Size(488, 269);
this.Controls.Add(this.statusBar1);
this.IsMdiContainer = true;
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
public void SetText(string val){ this.statusBar1.Text = val; }
[STAThread]
static void Main(){ Application.Run(new Form1()); }
}
public class Form2 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;

public Form2(){ InitializeComponent(); }

private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
// button1
this.button1.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
this.button1.Location = new System.Drawing.Point(24, 24);
this.button1.Name = "button1";
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
// textBox1
this.textBox1.Location = new System.Drawing.Point(24, 72);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(152, 19);
this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyDown);
// Form2
this.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
this.ClientSize = new System.Drawing.Size(216, 149);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form2";
this.ResumeLayout(false);
}
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
((Form1)MdiParent).SetText(this.Text + " textBox1_KeyDown!!");
}
private void button1_Click(object sender, System.EventArgs e)
{
((Form1)MdiParent).SetText(this.Text + " button1_Click!!");
}
}
}


発生方法を追記します。
1.Form1のボタンクリック
2.From2のテキストボックスクリック
3.From1のテキストボックスクリック
この状態で、Enterによるテキストボックスのキーダウンが発生せず、
From1のボタンクリックが発生します。
From2をアクティブにしてForm1をアクティブに戻すと、From1のテキストボックスの
キーダウンが発生するようになります。

[ メッセージ編集済み 編集者: こま 編集日時 2004-04-14 09:22 ]
こま
会議室デビュー日: 2004/03/18
投稿数: 5
投稿日時: 2004-04-28 11:34
自己RESです。

MSに問い合わせしたところバグという回答をいただきましたので、
ご参考のため掲載します。

以下回答抜粋−−−−−−−−−−−−−−−−−

[回答]

- 本現象の発生原因

MDI フォームにおいて、2つのMDI 子フォームを生成した場合に、2つ目の子フォームのボタンをクリックし、1つ目のフォームに戻った場合に、最後にクリックされたボタンが間違ってフォーカスを取得したまま離さないという障害がございます。

従いまして、Enterキーを押下しても上記のボタンが間違ってフォーカスを取得したままであるため、ボタンクリックイベントが間違って発生してしまう、という現象が発生しております。

本現象に関しては、弊社米国開発部門にて製品の障害と認識しております。


- 回避策

親Form の中で、下記 UpdateDefaultButton() メソッドをオーバーライドしていただくことで、本現象が回避可能です。

(下記の通り、何も処理を行わないようにオーバーライドして下さい。)



public class Form1 : System.Windows.Forms.Form

{

// ・・・ 略 ・・・



// オーバーライド

protected override void UpdateDefaultButton() { }

}

1

スキルアップ/キャリアアップ(JOB@IT)