Ответ 1
Немного сложно обнаружить операцию вставки в RichTextBox
.
Первое решение может заключаться в обнаружении сообщения WM_PASTE
, переопределяющего WndProc
, но, к сожалению, элемент управления не отправляет это сообщение самому себе, когда он выполняет операцию вставки.
Наивное обнаружение
Для обнаружения событий клавиатуры могут работать (вы должны переопределить функцию OnKeyDown
), затем проверьте, есть ли комбинации клавиш (CTRL + V и SHIFT + INS). Что-то вроде этого:
protected override OnKeyDown(KeyEventArgs e)
{
bool ctrlV = e.Modifiers == Keys.Control && e.KeyCode == Keys.V;
bool shiftIns = e.Modifiers == Keys.Shift && e.KeyCode == Keys.Insert;
if (ctrlV || shiftIns)
DoSomething();
}
Он работает хорошо, но вы не можете поймать операцию вставки, сделанную с помощью мыши (щелкните правой кнопкой мыши, чтобы открыть контекстное меню) и операции вставки, сделанные с помощью перетаскивания. Если они вам не нужны, вы можете использовать это решение (по крайней мере, это просто и просто).
Лучшее обнаружение
Предположение: когда пользователь вводит внутри RichTextBox
, он вставляет один символ за время. Как вы можете это использовать? Ну, когда вы обнаруживаете большее изменение, вы обнаружили операцию вставки, потому что пользователь не может вводить более одного символа за раз (хорошо, вы можете утверждать, что это не всегда верно из-за суррогатов Unicode). См. Также версия VB.NET и подробнее об Unicode.
private int _previousLength = 0;
private void richTextBox_TextChanged(object sender, EventArgs e)
{
int currentLength = richTextBox.Text.Length;
if (Math.Abs(currentLength - _previousLength) > 1)
ProcessAllLines();
_previousLength = currentLength;
}
Обратите внимание, что вы не можете (из-за того, как работают разные IME) использовать OnKeyDown
(или аналогичный). Это хорошо работает только для западных языков, но у него есть проблемы с материалом Unicode (потому что, например, свойство String.Length
может быть увеличено на два Char
, когда пользователь вводит один символ. См. Также этот пост для получения более подробной информации об этом (ну, это настоятельно рекомендуется прочитать даже, даже если - в этом случае - вам все равно). В этом посте вы также найдете код для лучшего алгоритм для определения длины строки. Короче говоря, вы должны заменить:
int currentLength = richTextBox.Text.Length;
При этом:
int currentLength = StringInfo.GetTextElementEnumerator(richTextBox.Text)
.Cast<string>()
.Count();
После всех этих усилий вы можете понять, что... пользователь может даже вставить один символ, и он может остаться незамеченным. Вы правы, поэтому это лучшее определение, а не идеальное решение.
Идеальное решение
Разумеется, идеальное решение (если вы работаете в Windows 8) существует, встроенный редактор edit edit отправляет сообщение уведомления EN_CLIPFORMAT
. Он предназначен для уведомления о расширенном родительском окне управления редактированием, в котором произошла вставка с определенным форматом буфера обмена. Затем вы можете переопределить WndProc
своего родителя, чтобы обнаружить сообщение WM_NOTIFY
для этого уведомления. В любом случае, это не так много строк кода, проверьте эту статью статью MSDN для деталей.