Вопрос по .net, syntax-highlighting, vb.net – Как обнаружить многострочную вставку в RichTextBox

1

В данный момент я работаю над простой подсветкой синтаксиса и у меня есть пара проблем. Не могли бы вы помочь мне?

У меня есть библиотека классов с классом компонента в нем. Все есть в VB.NET. Это только один файл, так что вы можете увидеть его здесьhttps://gist.github.com/2366507 , В строке 92 находится SubTextChanged Sub. Я думал о добавлении ProcessAllLines () (как в строке 128) в конец этого Sub, и это сработало. Однако, когда я набирал код в RichTextBox (источник, который я использовал, находится здесьhttps://gist.github.com/2366526) после каждого изменения текста он проверял и обрабатывал ВСЕ строки. Поэтому я удалил ProcessAllLines () в подпункте OnTextChanged.

Я думаю о запуске ProcessAllLines (), когда пользователь вставляет что-то в SyntaksRichTextBox. Однако я не знаю, как это сделать. Я знаю, что это должно быть что-то вроде:

If [CTRL Pressed] And [V Pressed] Then
ProcessAllLines()
End If

Я также хочу, чтобы это было в библиотеке классов, а не в приложении (Syntaks Demo). Не могли бы вы помочь мне здесь? Благодарю.

Рафал Чмиль, @RafalChmiel

Ваш Ответ

1   ответ
2
Naïve detection

WM_PASTE сообщение переопределяетWndProc но, к сожалению, элемент управления не отправляет это сообщение самому себе, когда выполняет операцию вставки.

Обнаружение событий клавиатуры (вы должны переопределитьOnKeyDown функция) и проверка, является ли комбинация клавиш (CTRL + V и SHIFT + INS) единственной для вставки текста, вы можете решить эту проблему.

Protected Sub OnKeyDown(ByVal e As KeyEventArgs)
    Dim ctrlV As Boolean = e.Modifiers = Keys.Control && e.KeyCode = Keys.V
    Dim shiftIns As Boolean = e.Modifiers = Keys.Shift && e.KeyCode = Keys.Insert

    If ctrlV Or shiftIns Then
        ProcessAllLines
    End If
End Sub

Оно работаетwell но вы не можете уловить операцию вставки, выполненную с помощью мыши (щелчок правой кнопкой мыши, чтобы открыть контекстное меню), и операции вставки, выполненные с помощью перетаскивания & amp; понижаться. Если они вам не нужны, вы можете использовать это решение (по крайней мере, оно простое и понятное).

Better detection

Предположение: когда пользователь вводит внутриRichTextBox он вставляет один символ за раз. Как вы можете использовать это? Хорошо, когда вы обнаружили большее изменение, вы обнаружили операцию вставки, потому что пользователь не может набирать более одного раза за раз (это не всегда так из-за суррогатов Unicode, но в этом случае это не проблема).

Он не очень хорошо работает с каждым IME (я не пробовал, например, с дальневосточными языками) и с суррогатами Unicode, но для западных языков все нормально (в любом случае, даже если он не работает, вы просто будете повторно обрабатывать все). линии). Также прочитайтеэта почта а такжеэта почта для получения более подробной информации о Unicode иэтот (близнец) ответ для версии C #.

Dim _previousLength As Int32 = 0

Protected Sub richTextBox_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
   Dim currentLength As Int32 = richTextBox.Text.Length
   If Math.Abs(currentLength - _previousLength) > 1 Then
      ProcessAllLines
   End If

   _previousLength = currentLength
End Sub
Perfect solution

Конечно, существует идеальное решение (в Windows 8 или более поздней версии).EN_CLIPFORMAT Уведомление Оно предназначено для уведомления родительского окна элемента управления расширенного редактирования о том, что вставка произошла с определенным форматом буфера обмена. Затем вы можете переопределитьWndProc его родителя, чтобы обнаружитьWM_NOTIFY сообщение для этого уведомления. В любом случае, это не несколько строк кода, проверьте эту ссылку на MSDN для деталей:http://msdn.microsoft.com/en-us/library/windows/desktop/hh768385(v=vs.85).aspx.

Я отредактировал свой первый комментарий.
Меня не волнует (пока) контекстное меню или перетаскивание. Он все равно не включен (контекстное меню) - не уверен насчет dragndrop thou.
@RafalChmiel Полагаю, этот код может ужаснуть многих людей, но мы сохраним секрет! ;)
@RafalChmiel, пожалуйста, но это не очень хорошее решение, оно не обнаружит, вставит ли пользователь какой-либо текст с помощью контекстного меню или с помощью перетаскивания. падение! Второе решение немного лучше.
Здравствуйте, большое спасибо за ваш ответ. Я искал что-то вроде первого фрагмента кода, который вы мне дали. Я преобразовал это в VB:gist.github.com/2367050 и вставил его прямо под SubTextChanged Sub, однако, похоже, он не работает. Я сделал это неправильно? Постскриптум Я также попробовал второе решение (похоже, тоже не сработало). Спасибо за ваше время. Полезный ответ однако!

Похожие вопросы