• 控制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,在实际应用中应该从配置文件中读取。

  • 相关阅读:
    《感旧》
    react入门
    放羊与砍柴
    chrome插件开发
    bean注入
    JAVA SPI 和ServiceLoader
    mysql的行转列与列转行
    Ignite实战
    Clickhouse基准测试实践
    Kafka Eagle 3.0.1功能预览
  • 原文地址:https://www.cnblogs.com/51net/p/10496344.html
Copyright © 2020-2023  润新知