我的程序在同時開啟多個MDI子窗體后﹐通過父窗體的MdiList菜單切換當前窗體進行操作.
此時會發生一個很奇怪的現象:
點擊一個窗體的一個按鈕,然后切換到其它窗口﹐再返回這個窗口﹐此時無論在哪個(非Button)控件上按回車鍵﹐都會觸發那個按鈕的Click事件. 事件的sender參數也是這個按鈕﹐但是當前窗體的ActiveControl并不是這個按鈕。我沒有設置任何窗體的AcceptButton和CancelButton﹐而且也沒有其它控件直接調用那個按鈕的Click方法。
為什么為這樣呢? 請高手們指點!感激不盡!!!!
若能解決問題,另開一貼100奉上!!!!
此時會發生一個很奇怪的現象:
點擊一個窗體的一個按鈕,然后切換到其它窗口﹐再返回這個窗口﹐此時無論在哪個(非Button)控件上按回車鍵﹐都會觸發那個按鈕的Click事件. 事件的sender參數也是這個按鈕﹐但是當前窗體的ActiveControl并不是這個按鈕。我沒有設置任何窗體的AcceptButton和CancelButton﹐而且也沒有其它控件直接調用那個按鈕的Click方法。
為什么為這樣呢? 請高手們指點!感激不盡!!!!
若能解決問題,另開一貼100奉上!!!!
由窗體的ActiveControl屬性可知﹐焦点是沒有的问题的!
而且值得一提的是: 再次切換MDIChild窗體后﹐又會恢復正常。
此时会发生一个很奇怪的现象:
点击一个窗体的一个按钮,然后切换到其它窗口﹐再返回这个窗口﹐此时无论在哪个(非Button)控件上按回车键﹐都会触发那个按钮的Click事件. 事件的sender参数也是这个按钮﹐但是当前窗体的ActiveControl并不是这个按钮。我没有设置任何窗体的AcceptButton和CancelButton﹐而且也没有其它控件直接调用那个按钮的Click方法。值得一提的是: 再次切换MDIChild窗体后﹐又会恢复正常。
消息队列试试
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(keyData == (Keys.Enter) && (Control.FromHandle(msg.HWnd) is Button))
return true;
else
return base.ProcessCmdKey(ref msg, keyData);
}
keyData==Return (Return!=Enter ??)
using System.Drawing;
using System.Windows.Forms;class TestForm : Form
{
Button btn;
TextBox txt; public TestForm()
{
btn = new Button();
btn.Text = "Click Me";
btn.Location = new Point(100,100);
Controls.Add(btn);
btn.Click += new EventHandler(Button_Click); txt = new TextBox();
txt.Location = new Point(100,200);
Controls.Add(txt);
} void Button_Click(Object sender, EventArgs e)
{
MessageBox.Show("hell");
//txt.Focus();
} protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(keyData == (Keys.Enter) && (Control.FromHandle(msg.HWnd) is Button))
return true;
else
return base.ProcessCmdKey(ref msg, keyData);
}
static void Main()
{
Application.Run(new TestForm());
}}
产生我所说的这种现象﹐详细操作步骤是这样的﹕
1.开启两个MdiChild窗体.(设名为: form1,form2)
2.点击form1的一个Button(名为button1),通过MdiList菜单切换到form2,点击form2中的任一控件.
3.再通过MdiList菜单切换到form1,此时点击其它控件(如一个TextBox)按Enter键﹐就会执行button1的Click事件.
或者,你自己跟踪一下程序吧,从头跟到尾
我的Button和Text都是放在pannel中的.此外一個窗體中有個treeview控件和繼承的combobox控件(不涉及焦點的轉換),
另一個form有一個datagrid控件.
其它沒有什么特別的啊!
MDI窗體:using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;namespace 測試
{
/// <summary>
/// Form1 的摘要描述。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuItem3;
/// <summary>
/// 設計工具所需的變數。
/// </summary>
private System.ComponentModel.Container components = null; public Form1()
{
//
// Windows Form 設計工具支援的必要項
//
InitializeComponent(); //
// TODO: 在 InitializeComponent 呼叫之後加入任何建構函式程式碼
//
} /// <summary>
/// 清除任何使用中的資源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows Form 設計工具產生的程式碼
/// <summary>
/// 此為設計工具支援所必須的方法 - 請勿使用程式碼編輯器修改
/// 這個方法的內容。
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
//
// mainMenu1
//
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1,
this.menuItem2,
this.menuItem3});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.MdiList = true;
this.menuItem1.Text = "windowlist";
//
// menuItem2
//
this.menuItem2.Index = 1;
this.menuItem2.Text = "form2";
this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
//
// menuItem3
//
this.menuItem3.Index = 2;
this.menuItem3.Text = "form3";
this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 15);
this.ClientSize = new System.Drawing.Size(488, 341);
this.IsMdiContainer = true;
this.Menu = this.mainMenu1;
this.Name = "Form1";
this.Text = "Form1"; }
#endregion /// <summary>
/// 應用程式的主進入點。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
} private void menuItem2_Click(object sender, System.EventArgs e)
{
Form2 frm=new Form2();
frm.MdiParent =this;
frm.Show();
} private void menuItem3_Click(object sender, System.EventArgs e)
{
Form3 frm=new Form3();
frm.MdiParent =this;
frm.Show();
}
}
}Form2:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;namespace 測試
{
/// <summary>
/// Form2 的摘要描述。
/// </summary>
public class Form2 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
/// <summary>
/// 設計工具所需的變數。
/// </summary>
private System.ComponentModel.Container components = null; public Form2()
{
//
// Windows Form 設計工具支援的必要項
//
InitializeComponent(); //
// TODO: 在 InitializeComponent 呼叫之後加入任何建構函式程式碼
//
} /// <summary>
/// 清除任何使用中的資源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows Form 設計工具產生的程式碼
/// <summary>
/// 此為設計工具支援所必須的方法 - 請勿使用程式碼編輯器修改
/// 這個方法的內容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(136, 40);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(16, 40);
this.textBox1.Name = "textBox1";
this.textBox1.TabIndex = 1;
this.textBox1.Text = "textBox1";
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 15);
this.ClientSize = new System.Drawing.Size(292, 173);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "Form2";
this.Text = "Form2";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.ResumeLayout(false); }
#endregion private void button1_Click(object sender, System.EventArgs e)
{
MessageBox.Show("Hello!");
}
}
}Form3:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;namespace 測試
{
/// <summary>
/// Form3 的摘要描述。
/// </summary>
public class Form3 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
/// <summary>
/// 設計工具所需的變數。
/// </summary>
private System.ComponentModel.Container components = null; public Form3()
{
//
// Windows Form 設計工具支援的必要項
//
InitializeComponent(); //
// TODO: 在 InitializeComponent 呼叫之後加入任何建構函式程式碼
//
} /// <summary>
/// 清除任何使用中的資源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows Form 設計工具產生的程式碼
/// <summary>
/// 此為設計工具支援所必須的方法 - 請勿使用程式碼編輯器修改
/// 這個方法的內容。
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(80, 72);
this.textBox1.Name = "textBox1";
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
//
// Form3
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 15);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.textBox1);
this.Name = "Form3";
this.Text = "Form3";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.ResumeLayout(false); }
#endregion
}
}
2。按Button1 ->出现对话框
3。选form3
4。选form2
5。按光标进入TextBox
6。按回车
7。对话框没出现,因为焦点不在Button1上
1. 点击form1的菜单:"form3","form2"
2. 当前窗口应为form2, 点击form2的"click"按钮.
3. 点击MDI窗体form1的第一个菜单"windowlist",菜单会显示已打开的两个窗体"form2"和"form3",选择"form3"
4. 点击form3的TextBox,随便输入几个字符.
5. 点击MDI窗体form1的第一个菜单"windowlist",选择"form2"
6. 点击form2的textbox1﹐按Enter看看是不是会出一个对话框啊?.
工具是繁体的2003 .net:
Microsoft Development Environment 2003 Version 7.1.3091
Microsoft .net Framework 1.1 Version 1.1.4322
按回车,会触发第二个按钮的Click Handler如果你对回车不感兴趣的话,这么做protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(keyData == (Keys.Enter))
{
return true;
} else
return base.ProcessCmdKey(ref msg, keyData);
}
一旦这种情况发生,其它控件(除Button外)都不能触发事件了.需要将窗体再次切换才能正常.
很多用户投诉了. 惨啊! 是不是C#的bug啊?
笨方法也能解決問題! 在每個form的Deactivate事件中加一句
this.ActiveControl =null;
就可以了! 不知能不能在MDI窗體中處理子窗體的切換事件,如果可以的話﹐就省事多了!
開心結貼!