private bool UpdateEventHandlers(bool checkEvents) { var needEvents = checkEvents && _textView.VisualElement.IsVisible && MarginActive; if (needEvents != _hasEvents) { _hasEvents = needEvents; if (needEvents) { _verticalScrollBar.Map.MappingChanged += OnMappingChanged; return(UpdateMatches()); } _verticalScrollBar.Map.MappingChanged -= OnMappingChanged; if (_search != null) { _search.Abort(); _search = null; } } return(false); }
/// <summary> /// Start a background search /// </summary> /// <returns> /// true if a either a search has been queued or if the adornments/margin have been cleared since the highlight was /// removed. /// </returns> private bool UpdateMatches(bool force = false) { if (_hasEvents) { //Do a new search if the highlight changed, there is no existing search, or the existing search was on the wrong snapshot. if (_search == null || _search.Snapshot != _textView.TextSnapshot || force) { //The text of the highlight changes ... restart the search. if (_search != null) { //Stop and blow away the old search (even if it didn't finish, the results are not interesting anymore). _search.Abort(); _search = null; } //The underlying buffer could be very large, meaning that doing the search for all matches on the UI thread //is a bad idea. Do the search on the background thread and use a callback to invalidate the visual when //the entire search has completed. _search = new BackgroundMarkerPlacement( _textView.TextSnapshot, _textView, delegate { ThreadHelper.JoinableTaskFactory.Run(async delegate { //Force the invalidate to happen on the UI thread to satisfy WPF await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); //Guard against the view closing before dispatcher executes this. if (!_isDisposed) { InvalidateVisual(); } }); }); return(true); } } return(false); }