对于电脑快捷键来说恐怕没什么比Ctrl+C和Ctrl+V更熟悉的了。

最近做了一个小程序,界面上有一个文本框,要做的事情就是把从别的地方复制内容后粘贴到文本框中,然后以自己处理后的格式显示出来。

为了方便说明问题,举个例子,把其他功能简化后只用最简单的例子来说明就是,我复制了一个文本"C",然后再从文本框上按Ctrl+V后想把它放到文本框里,现在程序要做的事是让文本框只显示我想显示的内容,而不管你复制来的东西。这样操作就变成了在文本框上粘贴后,文本框就显示"哈"。

当时一想,这还不简单,记性中只要在文本框的KeyDown事件里判断下是否按了ctrl+v然后再进行相应处理就可以了,因为当时已经有了一个粘贴菜单了,按下ctrl+v和点击粘贴菜单其实做的都是同一件事情。

简化界面如下

文本框的KeyDown事件与获取字符串的方法

         private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V) // 是否按下ctrl+v
{
textBox1.Text = GetText();// 简化操作,只返回一个哈
}
}
private string GetText()
{
string s = "哈";
// 一系列处理操作略掉,最后应返回处理过的字符串...
return s;
}

接着运行,不出意外,结果应该像我们想像的那样,在文本框上按下ctrl+v后文本框里应该只有一个"哈"字,但实际结果却出乎意料,我复制了一个文本"c",按下ctrl+v后竟然是这样的

当时就震惊,什么情况,"c"也粘贴进去了,后来想到还有事件参数里有个Handled属性,表示是否处理过此事件,可能忘了设置,然后修改代码如下

         private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V) // 是否按下ctrl+v
{
textBox1.Text = GetText();// 简化操作,只返回一个哈
e.Handled = true;
}
}

然后再运行,结果还是一样,不信您自己试下。Handled属性看来在按下事件里不起作用。

接着在KeyDown,KeyPress,KeyUp这三个事件下输出文本框内容看下到底在什么时候系统给自己添加复制的内容到文本框中的,测试代码

         private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V) // 是否按下ctrl+v
{
textBox1.Text = GetText();// 简化操作,只返回一个哈
e.Handled = true;
Console.WriteLine("KeyDown: " + textBox1.Text);
}
} private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
Console.WriteLine("KeyPress: " + textBox1.Text);
} private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
Console.WriteLine("KeyUp: " + textBox1.Text);
}

运行,复制文本"c",在文本框上按下ctrl+v快捷键,看VS输出如下

从输出窗口可以看出,在KeyPress事件后KeyUp事件前系统把复制的文本"c"插入到了文本框中。

这真是个不愉快的事,系统在KeyPress事件后和KeyUp事件前干了什么,我无法控制。但问题还得解决。

解决方法一:

既然系统把复制的内容粘贴到文本框里,把我把剪贴版的内容清空掉,我看你还怎么放。

         private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V) // 是否按下ctrl+v
{
textBox1.Text = GetText();// 简化操作,只返回一个哈
Clipboard.Clear();
}
}

这个方法虽然容易达到效果,但是简单粗暴了点,而且真正的应用中是要使用剪贴版里的内容的,如果是这样,那使用的人就会发现只要在程序里粘贴后,再粘贴到其他地方就会发现粘贴时没了内容,这样又该跟他们解释各种原因,我太懒,所以不用这种方式。

解决方法二:

既然文本框的值在KeyUp之前已经被剪贴版里的文本设置进去了,那我就在KeyUp事件下把我的值设置到文本框中不行吗?

答案是可以的,把KeyDown事件下的代码放到KeyUp事件下

         private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V) // 是否按下ctrl+v
{
textBox1.Text = GetText();// 简化操作,只返回一个哈
}
}

经过测试,这样虽然大至是解决了,不过有一个缺点,就是操作时想要让文本框显示处理过的值,操作时还得有点技巧才行,按ctrl+v时不能太快的按下与弹起,你得先按下ctrl键后不放,再按V键,然后先松开V键,再松开ctrl键,这样文本框才会显示"哈",不然只显示你复制的文本,你处理的文本就不会显示,而且显示时会先显示复制的文本+处理的文本(类似:"c哈"),然后才显示你处理过的值到文本框中,很明显示看出的一个文本框的值被改修的过程。

不过这个有技巧性的操作对于编辑部的人来说,让我想起了经典的程序员与上帝打赌的笑话,看来这样还不是比较好的方法。

解决方法三:

网上搜到一篇文章说用richTextBox在KeyDown事件下使用Handled属性是可以的,所以把原来的代码放到KeyDown事件下试试,测试了确实可以达到效果。

         private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V)
{
richTextBox1.Text = GetText();
e.Handled = true;
}
}

不过换控件,对我来说"代价"还是有点大,懒得换了...

解决方法四:

这也是最后采用的一种方法,先定义一个bool变量,表示是否按下ctrl+v快捷键,在KeyDown事件下进行判断设置为true,在KeyPress事件下进行判断文本框的值是否要设置和重置变量为false,这样就不用考虑技巧性操作的问题了,也不会明显的看出文本框先显示粘贴的文本再显示自己设置的值了。

         private bool isCtrlv = false;// 是否按下ctrl+v
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V) // 是否按下ctrl+v
{
isCtrlv = true;
}
} private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (isCtrlv)// 如果按下ctrl+v
{
textBox1.Text = GetText();
e.Handled = true;
}
isCtrlv = false;

没想到一个简单的ctrl+v操作竟然整得如此曲折,想像中应该是一帆风顺的正常按照自己想像当中出现的结果。

之前没有好好测试,算是一个坑了,如果你还有什么更好的方法能解决,可以分享下....

一个Ctrl+V下的问题的更多相关文章

  1. Ajax请求参数到一个URL包含下划线或者v(_、v)

    Ajax请求参数到一个URL包含下划线或者v 初学者的我,在F12时,看到这个地址就会很奇怪,不理解什么东西 经过查找了解到浏览器默认开启缓存,该参数不是其他请求所必须的,把它去掉不影响数据的获取 h ...

  2. selenium 键盘事件 模拟ctrl+v 然后键盘点击回车键

    #windows下执行 import win32api,win32con,win32clipboard as w #获取剪切板内容 def get_text(): w.OpenClipboard() ...

  3. c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字

    TextBox只允许输入数字,最大长度为10 //TextBox.ShortcutsEnabled为false 禁止右键和Ctrl+v private void txtNumber_KeyPress( ...

  4. Spring Tool Suite4(sts)复制粘贴卡顿(ctrl+v, ctrl+c)、按住ctrl也很卡

    最近在看<Spring in Action, Fifth Edition>,下载了Spring Tool Suite4,在使用的过程中发现了一些问题: 只要在复制粘贴(ctrl+c, ct ...

  5. 2019-3-22c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字

    TextBox 禁止复制粘贴 ShortcutsEnabled =false TextBox只允许输入数字,最大长度为10 //TextBox.ShortcutsEnabled为false 禁止右键和 ...

  6. js实现ctrl+v粘贴上传图片(兼容chrome、firefox、ie11)【转载】

    我们或多或少都使用过各式各样的富文本编辑器,其中有一个很方便功能,复制一张图片然后粘贴进文本框,这张图片就被上传了,那么这个方便的功能是如何实现的呢? 原理分析 提取操作:复制=>粘贴=> ...

  7. 如何屏蔽ctrl + v 粘贴事件,鼠标右键粘贴事件

    通常在自己的APP里的密码框,验证码框需要屏蔽复制,粘贴,怎么办呢? 有三种方法: 1 hook 此方法是最完全的,但由于hook是全局的,容易影响到其它代码. 2 子类化文本框, 重写OnPaste ...

  8. js实现ctrl+v粘贴图片或是截图

    浏览器环境:谷歌浏览器 1.ctrl+v粘贴图片都是监听paste时间实现的,复制的数据都存在clipboardData下面,虽然打印显示数据长度为0,但是还是可以获取数据的 2.打印clipboar ...

  9. Office 2016 word无法粘贴(Ctrl + V)

    最近下载了一个 Office 2016 专业版 使用,发现 word 无法使用 Ctrl + V 粘贴东西,由于经常需要复制粘贴东西,无法粘贴影响很大 查了很多资料,尝试过很多的方法,终于发现问题的所 ...

随机推荐

  1. Linux进程管理之task_struct结构

    转载:http://blog.csdn.net/npy_lp/article/details/7335187 内核源码:linux-2.6.38.8.tar.bz2 目标平台:ARM体系结构 进程是处 ...

  2. Python Counter()计数工具

    Table of Contents 1. class collections.Counter([iterable-or-mapping]) 1.1. 例子 1.2. 使用实例 2. To Be Con ...

  3. iOS企业应用Profile制作流程

    第一步:企业版iDP申请完成以后,访问iOS Dev Center:https://developer.apple.com/devcenter/ios/index.action 第二步:点击Log I ...

  4. docker 容器数据管理

    给容器添加一个数据卷 sudo docker run -d -P --name web -v /webapp training/webapp python app.py 可以在Dockerfile中使 ...

  5. app 性能优化的那些事

    来源:树下的老男孩 链接:http://www.jianshu.com/p/5cf9ac335aec iPhone上面的应用一直都是以流畅的操作体验而著称,但是由于之前开发人员把注意力更多的放在开发功 ...

  6. iOS - 混合开发

    5.oc 与 js 混合开发 PhoneGap 专门做混合开发的,已经被另一个公司收购. WebViewJavascriptBridge 国内用的比较多 混合开发的好处:跨平台性.H5开发的时间成本, ...

  7. redis存储对象,实体类新加字段空指针问题处理

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

  8. hdu 4598 差分约束

    思路:首先就是判断是否有奇环,若存在奇环,则输出No. 然后用差分约束找是否符合条件. 对于e(i,j)属于E,并且假设顶点v[i]为正数,那么v[i]-v[j]>=T--->v[j]-v ...

  9. 深入理解ThreadLocal(转)(2015年06月11日)

    注明:转自:http://my.oschina.net/clopopo/blog/149368 学习一个东西首先要知道为什么要引入它,就是我们能用它来干什么.所以我们先来看看ThreadLocal对我 ...

  10. 将java项目打包成jar文件并在cmd运行

    保证java项目不报错能够通过运行 选择export 选择一个你要运行的程序入口Main方法 打开cmd,前提是你的javajdk及环境变量配置完成