对于电脑快捷键来说恐怕没什么比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. HTTP权威指南学习心得

    一.HTTP请求的步骤: 1.从url中读取主机名 2.利用DNS(domain name service)对主机名进行转换,得到IP地址 3.如果有端口号的话,读取端口号 4.根据IP地址和端口号, ...

  2. postgres函数

    1.数据修复最先考虑通过db内做修复,实在不行,在考虑外部应用程序通过jdbc修复. 比如一个场景:profile_image_url与enlarge_image_url都是微博用户信息返回的字段. ...

  3. 100%会用到的angularjs的知识点【新手可mark】

    前言:下面我将整理出100%会到的angularjs的知识点,掌握这些知识点你基本上就可以独立完成一个angularjs的项目,前提是你有一定web开发的经验:1.了解基本的javascript的概念 ...

  4. How to make remote key fob for 2002 BMW 3 series

    Here share with you on how to make remote key fob for 2002 BMW 3 series: Method 1: 1. Working within ...

  5. [SEO] 网站标题分隔符

    标题用什么分隔符对SEO最有利 我们在看同行的朋友对网站标题优化时,关键词分按照主次的顺序进行分布,在网站标题或者是关键词之间都会有一个符号,俗话来讲就称为关键词分隔符,网站标 题分隔符分为“-”(横 ...

  6. TFS 2010 使用手册(一)安装与配置

    本文转自cnblogs 大辉狼 的文章: http://www.cnblogs.com/wph1129/archive/2010/11/10/1873348.html http://www.cnblo ...

  7. Shell学习笔记 - 环境变量配置文件

    一.source命令 功能:在当前bash环境下读取并执行配置文件中的命令 1. 命令格式 source 配置文件  或  . 配置文件 2. 命令示例 [root@localhost ~]# sou ...

  8. C# struct

    很困惑,为什么C#会有struct 这样一个关键字.虽然我用C#几年了,但绝少用到此关键字.我在相关书籍上学习C#的时候,看到过struct内容——但C#并不是我的第一入门语言,所以没有那么细致的学习 ...

  9. IFRAM的详细用法

    IFRAM的详细用法:   IFRAM的详细用法:  <IFRAME>用于设置文本或图形的浮动图文框或容器. BORDER <IFRAME BORDER="3"& ...

  10. JavaScript中的getBoundingClientRect()方法

    这个方法返回一个矩形对象,包含四个属性:left.top.right和bottom.分别表示元素各边与页面上边和左边的距离. getBoundClientRect()方法返回的对象中和CSS中所定义不 ...