C# 指定双击文本区域或文本框时的高亮显示行为?
我注意到,许多希望您进行大量文本编辑的应用程序将为双击文本提供非默认行为,因为应用程序会突出显示它认为您最有可能尝试与之交互的文本 举个简单的例子,这句话在不同的应用中表现不同: 这是一个“示例”句子 如果我在记事本中键入该内容,然后双击单词“sample”(理想情况下,在单词的中间,例如sample的“m”和“p”之间),则记事本将突出显示从第一个引号到第二个引号后的空格(包括)。如果该句子在VisualStudio中的注释中,并且我双击了同一位置,则它会从示例的“s”突出显示到“e”,而不会突出显示引号C# 指定双击文本区域或文本框时的高亮显示行为?,c#,text,highlighting,C#,Text,Highlighting,我注意到,许多希望您进行大量文本编辑的应用程序将为双击文本提供非默认行为,因为应用程序会突出显示它认为您最有可能尝试与之交互的文本 举个简单的例子,这句话在不同的应用中表现不同: 这是一个“示例”句子 如果我在记事本中键入该内容,然后双击单词“sample”(理想情况下,在单词的中间,例如sample的“m”和“p”之间),则记事本将突出显示从第一个引号到第二个引号后的空格(包括)。如果该句子在VisualStudio中的注释中,并且我双击了同一位置,则它会从示例的“s”突出显示到“e”,而不会
如何在自己的应用程序中自定义这些突出显示行为?winforms和WPF有什么不同吗?我想我可以破解我的方法,让它在双击事件上工作,但是有没有一个更优雅/更深思熟虑的解决方案专门针对这个问题?是的,使用双击事件来做你想做的事情是很困难的,因为它似乎做了两次选择,速度较慢,看起来更糟,并且可能触发不想要的事件/代码 因此,下面的代码至少应该对Winforms起作用。创建一个新类,并以通常的方式扩展TextBox(或RichTextBox)(使用新创建的控件,该控件应神奇地出现在设计器中)。我制作了一个简单的例程,您可以在其中指定要使用的分隔符。再多做一点工作,就可以很容易地解释一系列字符,而不仅仅是一个字符,甚至可以创建其他更高级的选择方法 如果您使用的是文本框而不是RichTextBox,只需删除类定义中出现两次的“Rich”位即可
class RichTextBoxX : RichTextBox
{
char delimiter = ','; // Specify what character to use for start and end of selection
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg==0x0203) // WM_LBUTTONDBLCLK
{
// Perfect situation for off-by-one bugs! Checked thoroughly for at least 10 mins, so should be okay now:
int start = this.SelectionStart;
if (start < 1) start = 1;
int left = this.Text.LastIndexOf(delimiter, start - 1);
int right = this.Text.IndexOf(delimiter, start);
if (right == -1) right = Text.Length;
this.SelectionStart = left + 1;
this.SelectionLength = right - left - 1;
return;
}
base.WndProc(ref m);
}
}
类RichTextBoxX:RichTextBox
{
字符分隔符=',';//指定用于选择的开始和结束的字符
受保护的覆盖无效WndProc(参考System.Windows.Forms.Message m)
{
如果(m.Msg==0x0203)//WM_lbuttondblck
{
//一个接一个bug的完美情况!彻底检查至少10分钟,现在应该可以了:
int start=this.SelectionStart;
如果(开始<1)开始=1;
int left=this.Text.LastIndexOf(分隔符,start-1);
int right=this.Text.IndexOf(分隔符,开始);
如果(right==-1)right=Text.Length;
this.SelectionStart=left+1;
this.SelectionLength=右-左-1;
返回;
}
基准WndProc(参考m);
}
}
在DanW的工作基础上,我添加了多个分隔符,看起来效果不错
class RichTextBoxX : RichTextBox
{
private char[] delimiterList = new[] { ',', ' '};
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg == 0x0203) // WM_LBUTTONDBLCLK
{
int start = this.SelectionStart;
if (start < 1) start = 1;
int left = -1;
int right = Text.Length;
foreach (char c in delimiterList)
{
if (this.Text.LastIndexOf(c, start - 1) > left)
{
left = this.Text.LastIndexOf(c, start - 1);
}
if (this.Text.IndexOf(c, start) < right)
{
right = this.Text.IndexOf(c, start);
if (right == -1) right = Text.Length;
}
}
this.SelectionStart = left + 1;
this.SelectionLength = right - left - 1;
return;
}
base.WndProc(ref m);
}
}
并将其替换为
this.richTextBox1 = new project.form1.RichTextBoxX();
在此之后,该控件将像普通RichTextBox实现一样工作,具有额外的overide功能的改进答案几乎对我有效,但是它有一个严重的错误:如果无法找到分隔符字符,Text.IndexOf(c,start)
将返回-1
,它将右侧设置为-1
,然后如果(右侧==-1)右侧=文本,则触发
所以现在我们已经选择了,直到文本结束,即使预期的选择应该更短。我认为启动操作是正确的
我删除了if(right==-1)right=Text.Length,但添加了&&pos!=-1
。以下是固定版本:
class RichTextBoxX : RichTextBox
{
// implement selection to work with "whole words" on double-click
// and without selecting the leading/trailing spaces/blanks/line breaks
private char[] delimiterList = new[] { '\n', ',', ' ', '(', ')', '_', '/' };
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0203) // WM_LBUTTONDBLCLK
{
int start = SelectionStart;
if (start < 1) start = 1;
int left = -1;
int right = Text.Length;
int pos;
foreach (char c in delimiterList)
{
pos = Text.LastIndexOf(c, start - 1);
if (pos > left) left = pos;
pos = Text.IndexOf(c, start);
if (pos < right && pos != -1) right = pos;
}
SelectionStart = left + 1;
SelectionLength = right - left - 1;
return;
}
base.WndProc(ref m);
}
}
我添加了一些其他的分隔符,请随意选择您需要的内容。我使用Regex\w
,它等于[a-zA-Z0-9.
来替换文本框
选择
private void TextBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
string text = TextBox1.SelectedText;
var strA = Regex.Match(text, @"\w+");
int indexA = TextBox1.SelectionStart + text.IndexOf(strA.Value);
TextBox1.Select(indexA, strA.Value.Length);
}
原始结果:
这是一个“示例”
句子
使用上述方法
这是一个“示例
”句子我的答案有用吗?或者这个问题是一个死问题?如果我想做我自己的事情,你的答案就是我会做的。我一直在寻找一种面向事件驱动、上下文敏感的方法,以便为双击时突出显示的文本设置自定义条件。显然没有办法做到这一点。如何获得多个分隔符,你能给出一个带有char[]的示例吗?小心,请参见上面Eugen的答案。
12.34.56.78 (ab1-2-3-4-5.test-1.example.com)
Jersey City
New Jersey
US, United States
ASN: Example.com/12345
private void TextBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
string text = TextBox1.SelectedText;
var strA = Regex.Match(text, @"\w+");
int indexA = TextBox1.SelectionStart + text.IndexOf(strA.Value);
TextBox1.Select(indexA, strA.Value.Length);
}