菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
77
0

Ctrl-A全选

原创
05/13 14:22
阅读数 96041

Ctrl-A全选这点事(C#,WinForm)

 

      所有的文本框,不管单行多行都Ctrl-A全选就好了吧?是啊,很方便。Windows的软件基本都是这样。可为什么我们自己制作的WinForm就默认不是这样呢?谁知道呢,可能是WinForm饱受诟病,要改变一下,不想再封装太多默认功能吧。反正程序员自己加这点功能也不难。

      好了,以上是YY。接下来正式开始。

      一开始,我在自己的WinForm的某个文本框内按Ctrl-A,它没有全选,而且发出“噔”一声,提醒我按了一个无效的按键。于是很简单的,加了以下代码,实现了“这一个”文本框的Ctrl-A实现全选功能。

复制代码
private void TextBox_KeyPress(object sender, KeyPressEventArgs e)
{
    TextBox textBox = sender as TextBox;
    if (textBox == null)
        return;
    if (e.KeyChar == (char)1)       // Ctrl-A 相当于输入了AscII=1的控制字符
    {
        textBox.SelectAll();
        e.Handled = true;      // 不再发出“噔”的声音
    }
}
复制代码

并由属性编辑器或自己在代码中实现了事件的注册: textBox.KeyPress += TextBox_KeyPress; 

     这样就完事了,真是“这点事”。等等,如果我有30个TextBox不是要写30行注册代码?能不能写个什么一次搞定,整个WinForm内的所有TextBox都支持Ctrl-A,最好连动态加载的TextBox也支持。于是我在Form的ControlAdded事件中判断如果新添加的Control是TextBox则注册KeyPress事件处理方法。

复制代码
private void Control_ControlAdded(object sender, ControlEventArgs e)
{
    TextBox textBox = e.Control as TextBox;
    if (textBox != null)
    {
        textBox.KeyPress += TextBox_KeyPress;
    }
}
public Form1()
{
    this.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.Control_ControlAdded);
    InitializeComponent();
}
复制代码

代码运行后,发现部分TextBox有效果,部分没效果。经过调试,发现,直接跟在WinForm(Form1)的有效果,在用户控件(UserControl)中的TextBox则无效果。对照一下代码,是啊,我还应该处理UserControl的ControlAdded事件,哦不,是所有Control的ControlAdded事件。而且控件还会包含控件,所有子子孙孙控件都注册这个事件,这样任何新添加的控件都会被判断是否为TextBox,于是Control_ControlAdded变成这个样子:

复制代码
private void Control_ControlAdded(object sender, ControlEventArgs e)
{
    //使“未来”生效
    e.Control.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.Control_ControlAdded);
    //使“子孙”生效
    foreach (Control c in e.Control.Controls)
    {
        Control_ControlAdded(sender, new ControlEventArgs(c));
    }
    //使“过去”生效
    TextBox textBox = e.Control as TextBox;
    if (textBox != null)
    {
        textBox.KeyPress += TextBox_KeyPress;
    }
}
复制代码

经测试,通过。一劳永逸地解决了这个问题,从此不再为这个问题而费神。


2016-04-27补充:在最终版本的Control_ControlAdded方法加上3行注释,从时空的角度来描述原理,让各位看明白它的覆盖范围。由于同时处理了过去和未来,所以 this.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.Control_ControlAdded); 这一句不一定要放在 InitializeComponent(); 之前。放哪都行,执行后就整个Form(this)的TextBox有效。

      所有的文本框,不管单行多行都Ctrl-A全选就好了吧?是啊,很方便。Windows的软件基本都是这样。可为什么我们自己制作的WinForm就默认不是这样呢?谁知道呢,可能是WinForm饱受诟病,要改变一下,不想再封装太多默认功能吧。反正程序员自己加这点功能也不难。

      好了,以上是YY。接下来正式开始。

      一开始,我在自己的WinForm的某个文本框内按Ctrl-A,它没有全选,而且发出“噔”一声,提醒我按了一个无效的按键。于是很简单的,加了以下代码,实现了“这一个”文本框的Ctrl-A实现全选功能。

复制代码
private void TextBox_KeyPress(object sender, KeyPressEventArgs e)
{
    TextBox textBox = sender as TextBox;
    if (textBox == null)
        return;
    if (e.KeyChar == (char)1)       // Ctrl-A 相当于输入了AscII=1的控制字符
    {
        textBox.SelectAll();
        e.Handled = true;      // 不再发出“噔”的声音
    }
}
复制代码

并由属性编辑器或自己在代码中实现了事件的注册: textBox.KeyPress += TextBox_KeyPress; 

     这样就完事了,真是“这点事”。等等,如果我有30个TextBox不是要写30行注册代码?能不能写个什么一次搞定,整个WinForm内的所有TextBox都支持Ctrl-A,最好连动态加载的TextBox也支持。于是我在Form的ControlAdded事件中判断如果新添加的Control是TextBox则注册KeyPress事件处理方法。

复制代码
private void Control_ControlAdded(object sender, ControlEventArgs e)
{
    TextBox textBox = e.Control as TextBox;
    if (textBox != null)
    {
        textBox.KeyPress += TextBox_KeyPress;
    }
}
public Form1()
{
    this.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.Control_ControlAdded);
    InitializeComponent();
}
复制代码

代码运行后,发现部分TextBox有效果,部分没效果。经过调试,发现,直接跟在WinForm(Form1)的有效果,在用户控件(UserControl)中的TextBox则无效果。对照一下代码,是啊,我还应该处理UserControl的ControlAdded事件,哦不,是所有Control的ControlAdded事件。而且控件还会包含控件,所有子子孙孙控件都注册这个事件,这样任何新添加的控件都会被判断是否为TextBox,于是Control_ControlAdded变成这个样子:

复制代码
private void Control_ControlAdded(object sender, ControlEventArgs e)
{
    //使“未来”生效
    e.Control.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.Control_ControlAdded);
    //使“子孙”生效
    foreach (Control c in e.Control.Controls)
    {
        Control_ControlAdded(sender, new ControlEventArgs(c));
    }
    //使“过去”生效
    TextBox textBox = e.Control as TextBox;
    if (textBox != null)
    {
        textBox.KeyPress += TextBox_KeyPress;
    }
}
复制代码

经测试,通过。一劳永逸地解决了这个问题,从此不再为这个问题而费神。


2016-04-27补充:在最终版本的Control_ControlAdded方法加上3行注释,从时空的角度来描述原理,让各位看明白它的覆盖范围。由于同时处理了过去和未来,所以 this.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.Control_ControlAdded); 这一句不一定要放在 InitializeComponent(); 之前。放哪都行,执行后就整个Form(this)的TextBox有效。

发表评论

0/200
77 点赞
0 评论
收藏
为你推荐 换一批