控制WinForm中Tab鍵的跳轉


一,需求

在Winform中,默認情況下,按下Tab鍵,光標會按照我們設定的TabIndex值從小到大進行跳轉。

但如果用戶要求按下Tab鍵跳轉到特定的控件,這種要求還是很合理的,比如用戶只想輸入幾個必須填的項目。

我們可以在配置文件中配置這些必須填寫的項目,並設定他們的跳轉順序。這樣程序也更加靈活,利於擴展。

二,探索實現方法

1,在每個輸入控件的keyDown事件里判斷是Tab鍵,做相應的跳轉處理。

最后調查發現按下Tab鍵,並不會觸發控件keyDown事件,Tab鍵默認被系統處理了,悲劇了。

另外,輸入項目太多的時候,這個做法工作量也太大了,不可行。

2,找一個全局點控制,而不分散到每個控件來處理。

方法就是利用Form本身的ProcessCmdKey方法。

看代碼吧,備注已經寫的很明白了

  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,在實際應用中應該從配置文件中讀取。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM