在Winform中,默認狀況下,按下Tab鍵,光標會按照咱們設定的TabIndex值從小到大進行跳轉。ide
但若是用戶要求按下Tab鍵跳轉到特定的控件,這種要求仍是很合理的,好比用戶只想輸入幾個必須填的項目。函數
咱們能夠在配置文件中配置這些必須填寫的項目,並設定他們的跳轉順序。這樣程序也更加靈活,利於擴展。this
最後調查發現按下Tab鍵,並不會觸發控件keyDown事件,Tab鍵默認被系統處理了,悲劇了。spa
另外,輸入項目太多的時候,這個作法工做量也太大了,不可行。code
方法就是利用Form自己的ProcessCmdKey方法。orm
看代碼吧,備註已經寫的很明白了blog
Dictionary<string, string> tabMap = new Dictionary<string, string>(); private void InitTabMap() { // 加入From,To的控件名稱,表示按下Tab鍵從From跳掉To位置 tabMap.Add("textBox3", "textBox7"); tabMap.Add("textBox7", "textBox8"); } /// <summary> /// 這個重載函數裏能夠預先捕捉到一些按鍵,好比被系統默認捕獲了的Tab鍵 /// 若是要改寫Tab鍵的默認動做,要返回true,表示你已經處理過這個按鍵了 /// </summary> /// <param name="msg"></param> /// <param name="keyData"></param> /// <returns></returns> protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { Control ctl = this.ActiveControl; if (keyData == Keys.Tab) { if (ctl != null && tabMap.Keys.Contains(ctl.Name)) { var toCtrls = this.Controls.Find(tabMap[ctl.Name], true); if (toCtrls.Length > 0) { //檢查父容器是不是隱藏的 ActivieParentContainerIfNeeded(toCtrls[0]); toCtrls[0].Focus(); //確實得到了焦點,再吞噬這個按鍵動做 if (toCtrls[0].Focused) { return true; } } } } bool ret = base.ProcessCmdKey(ref msg, keyData); return ret; } /// <summary> /// 有一些控件隱藏在了TabControl的後面,形成Focus不成功。 /// 由於這些控件的Visible爲False,必須先使他們的父控件TabPage先選中 /// </summary> /// <param name="child"></param> private void ActivieParentContainerIfNeeded(Control child) { if (child.Visible) { return; } Control parent = child.Parent; while (parent != null) { if (parent is TabPage) { break; } parent = parent.Parent; } if (parent is TabPage) { TabControl tabCtrl = (TabControl)parent.Parent; tabCtrl.SelectedTab = (parent as TabPage); } }
上面的tabMap,在實際應用中應該從配置文件中讀取。事件