对于电脑快捷键来说恐怕没什么比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. 【阿里云产品公测】ACE、BAE及SAE云引擎对比评测

    作者:阿里云用户bailimei 先前我已发布一篇关于ACE的评测,在跟朋友聊天的时候我们讨论了目前市面上的三款云引擎产品,这三家的云引擎我都有在用,今天有时间顺便写篇关于阿里云ACE.百度BAE和新 ...

  2. 【阿里云产品公测】云引擎ACE新手实战基于Wordpress

    [阿里云产品公测]云引擎ACE新手实战基于Wordpress 作者:阿里云用户imnpc ACE(Aliyun Cloud Engine) 是一款弹性.分布式的应用托管环境,支持Java.php多种语 ...

  3. MS SQL SERVER 中的系统表

    MS SQL SERVER 中的系统表 序号 名称 说明 备注 1 syscolumns 每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行.   2 syscomments 包含每 ...

  4. hibernate中session的获取使用以及其他注意事项

    hibernate中session的获取使用以及其他注意事项 前言:工作时,在同时使用Hibernate的getSession().getHibernateTemplate()获取Session后进行 ...

  5. oracle冷备份

    windows环境下Oracle数据库冷备份和恢复 1.点击开始菜单的“运行”,输入sqlplus/nolog 2.在弹出的命令行窗口以sysdba身份登陆,要输入:系统用户名/登陆密码@数据库实例名 ...

  6. Java为什么只能单继承?

    就是因为C++里多重继承功能强大但是容易出错,Java才给取消掉了.如果,A和B都继承于C,再写个D继承A和B.那么C里面有个方法,A和B继承过去后都进行了覆盖,那么D到底是该继承A里面的版本呢还是B ...

  7. php实现二路归并排序

    $arr = [9, 43, 12, 0, 87, 1]; function merge_sort(&$arr){ _merge_sort($arr, $arr, 0, count($arr) ...

  8. 如何调试异步加载的js文件(浏览器调试动态加载js)

    描述 1:jQuery->var obj= new $.js_Obj():等异步加载js文件,执行方法. obj.method(): 2:页面估计不变,通过声明不同的js文件,进行页面内容的转换 ...

  9. VS预生成事件命令行 和 生成后事件命令行

    宏                                                      说明 $(ConfigurationName)            当前项目配置的名称( ...

  10. Table of Contents - JavaSE

    Java Bean Lombok IO Commons-IO - IOUtils Regular Expression 正则表达式常用操作 Concurrency java.util.concurre ...