一个Ctrl+V下的问题
对于电脑快捷键来说恐怕没什么比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下的问题的更多相关文章
- Ajax请求参数到一个URL包含下划线或者v(_、v)
Ajax请求参数到一个URL包含下划线或者v 初学者的我,在F12时,看到这个地址就会很奇怪,不理解什么东西 经过查找了解到浏览器默认开启缓存,该参数不是其他请求所必须的,把它去掉不影响数据的获取 h ...
- selenium 键盘事件 模拟ctrl+v 然后键盘点击回车键
#windows下执行 import win32api,win32con,win32clipboard as w #获取剪切板内容 def get_text(): w.OpenClipboard() ...
- c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字
TextBox只允许输入数字,最大长度为10 //TextBox.ShortcutsEnabled为false 禁止右键和Ctrl+v private void txtNumber_KeyPress( ...
- Spring Tool Suite4(sts)复制粘贴卡顿(ctrl+v, ctrl+c)、按住ctrl也很卡
最近在看<Spring in Action, Fifth Edition>,下载了Spring Tool Suite4,在使用的过程中发现了一些问题: 只要在复制粘贴(ctrl+c, ct ...
- 2019-3-22c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字
TextBox 禁止复制粘贴 ShortcutsEnabled =false TextBox只允许输入数字,最大长度为10 //TextBox.ShortcutsEnabled为false 禁止右键和 ...
- js实现ctrl+v粘贴上传图片(兼容chrome、firefox、ie11)【转载】
我们或多或少都使用过各式各样的富文本编辑器,其中有一个很方便功能,复制一张图片然后粘贴进文本框,这张图片就被上传了,那么这个方便的功能是如何实现的呢? 原理分析 提取操作:复制=>粘贴=> ...
- 如何屏蔽ctrl + v 粘贴事件,鼠标右键粘贴事件
通常在自己的APP里的密码框,验证码框需要屏蔽复制,粘贴,怎么办呢? 有三种方法: 1 hook 此方法是最完全的,但由于hook是全局的,容易影响到其它代码. 2 子类化文本框, 重写OnPaste ...
- js实现ctrl+v粘贴图片或是截图
浏览器环境:谷歌浏览器 1.ctrl+v粘贴图片都是监听paste时间实现的,复制的数据都存在clipboardData下面,虽然打印显示数据长度为0,但是还是可以获取数据的 2.打印clipboar ...
- Office 2016 word无法粘贴(Ctrl + V)
最近下载了一个 Office 2016 专业版 使用,发现 word 无法使用 Ctrl + V 粘贴东西,由于经常需要复制粘贴东西,无法粘贴影响很大 查了很多资料,尝试过很多的方法,终于发现问题的所 ...
随机推荐
- debian7 更换GCC版本
最近在编译qt,之前用的是debian6,gcc版本是gcc-4.4,当使用debian7时,编译遇到了很多跟debian6不一样的问题,debian7的默认gcc使用的是gcc-4.7,可能是编译器 ...
- postgres函数
1.数据修复最先考虑通过db内做修复,实在不行,在考虑外部应用程序通过jdbc修复. 比如一个场景:profile_image_url与enlarge_image_url都是微博用户信息返回的字段. ...
- Eclipse中配置Tomcat碰到Server Tomcat v6.0 Server at localhost failed to start问题
控制台打印异常如下: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/juli/logg ...
- nodejs 安装 postgresql module
# npm -gd install node-gyp # export PATH=$PATH:/usr/local/pgsql/bin # npm -gd install pg for test: # ...
- sphinx-2.2.10-1.rhel6.x86_64 rpm包安装的位置
/etc/logrotate.d/sphinx /etc/rc.d/init.d/searchd/etc/sphinx/etc/sphinx/sphinx.conf/usr/bin/indexer/u ...
- js 数组中随机出来N组
var word = []; while (word.length < 7) { var tmp = data[parseInt(Math.random() * data.length)]; v ...
- Pascal 语言中二维数组:矩阵问题
[题目]方阵填数:在一个 N*N的方阵中,填入 1,2..... N*N个数,并要求构成如下格式: 图例:10 11 12 1 9 16 13 2 8 ...
- Ajax+JSON学习笔记(二)
来源:http://www.imooc.com/learn/250 readyState属性 0:请求未初始化,open还没有调用 1:服务器连接已建立,open已经调用了 2:请求已接受,也就是接收 ...
- web前端开发控件学习笔记之jqgrid+ztree+echarts
版权声明:本文为博主原创文章,转载请注明出处. 作为web前端初学者,今天要记录的是三个控件的使用心得,分别是表格控件jqgrid,树形控件ztree,图表控件echarts.下边分别进行描述. ...
- 设置WinForm窗体及程序图标
自己留着看,总是用的时候给忘记了,百度来百度去的麻烦. 设置 Ico 图标为 [资源文件] 项目名à右键à属性,在选项卡中选择"资源" 选择 "添加资源"à ...