Проблемы, предлагающие языковой сервис
Я нашел два способа предложить языковой сервис в интернете.
Первый способ предполагает использование IOleComponentManager
и регистрация таймера для вызова моей службы во время простоя.
Второй способ заключается в том, чтобы оформить мой сервис как IServiceContainer
и добавив ServiceCreatorCallback
"предложить услугу по требованию".
Предположительно, второй способ теперь является "предпочтительным" способом ведения дел. К сожалению, когда я использую этот метод, OnSynchronizeDropdowns
никогда не вызывается на мой TypeAndMembersDropdownBars
реализация.
Кроме того, когда мой LanguageService
находит ошибки в файле, он использует ParseRequest.Sink.AddError()
добавить ошибки в список ошибок. При предложении "По требованию" эти ошибки не отображаются в графическом интерфейсе, хотя я вижу, что они добавляются при отладке кода.
Я знаю, что моя языковая служба регистрируется, поскольку подсветка синтаксиса, "Перейти к определению" и "Найти все ссылки" по-прежнему работают.
Вот код, который я использую, чтобы "предложить свой сервис по требованию":
IServiceContainer serviceContainer = this as IServiceContainer;
ServiceCreatorCallback callback = new ServiceCreatorCallback(CreateLanguageService);
serviceContainer.AddService(typeof(MyLanguageService), callback, true);
Может кто-нибудь сказать мне, почему некоторые функции моего LanguageService
не работает, предлагая его по требованию? Я что-то упустил или просто не предназначен для полнофункциональной языковой службы?
1 ответ
Похоже, что по крайней мере отсутствующая функциональность требует использования IOleComponentManager
метод, который регистрирует таймер для вызова языковой службы в периоды простоя.
Используя dotPeek, я обнаружил, что OnSynchronizeDropdowns()
вызывается из OnCaretMoved()
для синхронизации выбранного элемента при нажатии в редакторе. OnCaretMoved()
само по себе, кажется, вызывается только из LanguageService.OnIdle()
метод, который я считаю, требует использования таймера простоя.
Еще покопавшись, я также обнаружил, что список ошибок требует, чтобы ParseRequest.Reason
быть установленным ParseReason.Check
в противном случае он игнорирует вызов. Копая код еще немного, единственное место, где я обнаружил, что причина разбора была в Source.OnIdle()
,
Обновление: я полагаю, что я подтвердил, что регистрация таймера простоя необходима для этих двух функций. Из MSDN на LanguageService.OnIdle:
Примечание. Этот метод не вызывается, пока вы не настроите свой собственный таймер и не вызовете этот метод из обработчика таймера.
Базовый метод вызывает OnCaretMoved, если каретка перемещена с момента последнего вызова OnIdle. Затем базовый метод вызывает метод OnIdle объекта Source для текущего представления. Если текущий объект Source не может быть получен, базовый метод вообще ничего не делает, в том числе не вызывает OnCaretMoved.