一,需求

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

控制WinForm中Tab键的跳转的更多相关文章

  1. 远程桌面中Tab键不能补全的解决办法

    我们曾在之前的一篇文章中介绍了windows远程连接ubuntu的方法,在成功登陆远程桌面环境之后,发现在终端中Tab键不能自动补齐(但是Ctrl +Tab 可以用,但是需要按下组合键才能补全的话,时 ...

  2. 在VNC中Xfce4中Tab键失效的解决方法

    说明 在Ubuntu Server 14.04上安装了xfce4桌面环境,但是却发现在终端中Tab键不能自动补齐(但是Ctrl + I 仍然可以用). 出现这种情况的原因是,由于Tab键的功能被窗口快 ...

  3. ubuntu VNC中Xfce4中Tab键失效的解决方法

    转:https://blog.csdn.net/xuezhisdc/article/details/48662435 说明 在Ubuntu Server 14.04上安装了xfce4桌面环境,但是却发 ...

  4. source insight 中tab键的设置

    转:http://xinzero.com/source-insight-code-alignment-ended.html source insight代码对齐Tab键终极版 以前也写过一个sourc ...

  5. 如何设置vim中tab键缩进---配置初始化设置

    转载自:http://blog.51cto.com/xuding/1725376:加了一些补充说明 问题: Linux系统下,Tab键默认为8个字符,需呀将其修改为4个字符的方式使用 步骤: 1.在用 ...

  6. Python中tab键自动补全功能的配置

    新手学习Python的时候,如何没有tab键补全功能,我感觉那将是一个噩梦,对于我们这种菜鸟来说,刚接触python,对一切都不了解,还好有前辈们的指导,学习一下,并记录下来,还没有学习这个功能小伙伴 ...

  7. C# winform中组合键奇怪不响应问题

    再winform中使用ProcessCmdKey处理快捷键响应,针对单一快捷键响应没有任何问题.但是针对组合键总是无法响应,如下: protected override bool ProcessCmd ...

  8. 怎样设置linux中Tab键的宽度(可永久设置)

    和我的上篇文章一样,能够设置当前用户的Tab键宽度.也能够设置全部用户的Tab键宽度 一.仅设置当前用户的Tab键宽度 输入命令:vim ~/.vimrc 然后:set tabstop=4   //我 ...

  9. 设置linux中Tab键的宽度(可永久设置)

    一.仅设置当前用户的Tab键宽度输入命令:vim ~/.vimrc然后:set tabstop=6   //将Tab键的宽度设置为6保存:ctrl+z+z(或:wq!)OK!二.设置所有用户的Tab键 ...

随机推荐

  1. 2018牛客网暑假ACM多校训练赛(第四场)C Chiaki Sequence Reloaded (组合+计数) 或 数位dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round4-C.html 题目传送门 - https://www.no ...

  2. CSS规范 - 分类方法

    CSS文件的分类和引用顺序 通常,一个项目我们只引用一个CSS,但是对于较大的项目,我们需要把CSS文件进行分类. 我们按照CSS的性质和用途,将CSS文件分成“公共型样式”.“特殊型样式”.“皮肤型 ...

  3. HDU 3415 Max Sum of Max-K-sub-sequence【单调队列】

    <题目链接> 题目大意: 给你一段从1~N的圆形序列,要你求出这段圆形序列中长度不超过K的最大连续子序列之和是多少,并且输出这子序列的起点和终点. 解题分析: 既然是求连续子序列之和,我们 ...

  4. 【java并发核心八】Fork-Join分治编程

    jdk1.7中提供了Fork/Join并行执行任务框架,主要作用就是把大任务分割成若干个小任务,再对每个小任务得到的结果进行汇总. 正常情况下,一些小任务我们可以使用单线程递归来实现,但是如果要想充分 ...

  5. linux 学习笔记 rpm命令

    软件包管理 用rpm命令来管理rpm 软件包 1>遵循GPL 规则 2>安装 foo-2.0-1.i386.rpm软件包 #rpm -ivh foo-1.0-1.i386.rpm 3> ...

  6. shell编程第一天

    shell编程基础 脚本:简单来说就是一条条的文字命令(一些指令的堆积)Shell属于内置的脚本 1.程序开发效率非常高,依赖于功能强大的命令可以迅速地完成开发任务(批处理) 2.语法简单,代码写起来 ...

  7. SpringBoot的国际化使用

    在项目中,很多时候需要国际化的支持,这篇文章要介绍一下springboot项目中国际化的使用. 在这个项目中前端页面使用的thymeleaf,另外加入了nekohtml去掉html严格校验,如果不了解 ...

  8. 自己总结的C#编码规范--1.命名约定篇

    命名约定 我们在命名标识符时(包括参数,常量,变量),应使用单词的首字母大小写来区分一个标识符中的多个单词,如UserName. PascalCasing PascalCasing包含一到多个单词,每 ...

  9. SQLite限定行数

    SELECT * FROM "spbak" ORDER BY intime desc limit 0,100;

  10. UVA 1592 DataBase

    思路: 知识补充: ①make_pair和pair: /*pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存.另一个应用 ...