Улучшенный ответ от DarkPh03n1X почти работал для меня, однако у него есть неприятная ошибка: если символ разделителя не может быть найден , Text.IndexOf(c, start)
вернет -1
который установит right
в -1
, а затем if (right == -1) right = Text.Length
сработает.
Так что теперь мы выбрали до конца текста, хотя ожидаемый выбор должен быть короче. Думаю, старт сделан правильно.
Я удалил 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);
}
}
Чтобы проверить поведение, вот пример текста, который я использовал:
12.34.56.78 (ab1-2-3-4-5.test-1.example.com)
Jersey City
New Jersey
US, United States
ASN: Example.com/12345
Я добавил несколько других разделителей, не стесняйтесь выбирать, что вам нужно.