private void FindAndHighlightText(string textToFind) { ClearAllHighlightedWords(); ITextRange searchRange = editor.Document.GetRange(0, TextConstants.MaxUnitCount); searchRange.Move(0, 0); bool textFound = true; do { if (searchRange.FindText(textToFind, TextConstants.MaxUnitCount, FindOptions.None) < 1) { textFound = false; } else { ITextRange ss = searchRange.GetClone(); m_highlightedWords.Add(searchRange.GetClone()); ITextCharacterFormat charFormatting = searchRange.CharacterFormat; charFormatting.BackgroundColor = Colors.Yellow; searchRange.CharacterFormat = charFormatting; } } while (textFound); }
internal void UpdateTextRange(ITextRange range) { bool rangeStartChanged = RangeStart != range.StartPosition; bool rangeEndChanged = RangeEnd != range.EndPosition; bool positionChanged = _range == null || rangeStartChanged; _range = range.GetClone(); RangeStart = _range.StartPosition; RangeEnd = _range.EndPosition; if (rangeStartChanged) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RangeStart))); } if (rangeEndChanged) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RangeEnd))); } if (positionChanged) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Position))); } }
private bool TryCommitSuggestionIntoDocument(ITextRange range, string displayText, Guid id, ITextCharacterFormat format, bool addTrailingSpace = true) { // We don't want to set text when the display text doesn't change since it may lead to unexpected caret move. range.GetText(TextGetOptions.NoHidden, out var existingText); if (existingText != displayText) { range.SetText(TextSetOptions.Unhide, displayText); } var formatBefore = range.CharacterFormat.GetClone(); range.CharacterFormat.SetClone(format); PadRange(range, formatBefore); range.Link = $"\"{id}\""; // In some rare case, setting Link can fail. Only observed when interacting with Undo/Redo feature. if (range.Link != $"\"{id}\"") { range.Delete(TextRangeUnit.Story, -1); return(false); } if (addTrailingSpace) { var clone = range.GetClone(); clone.Collapse(false); clone.SetText(TextSetOptions.Unhide, " "); clone.Collapse(false); TextDocument.Selection.SetRange(clone.EndPosition, clone.EndPosition); } return(true); }
/// <summary> /// Pad range with Zero-Width-Spaces. /// </summary> /// <param name="range">Range to pad.</param> /// <param name="format">Character format to apply to the padding.</param> private static void PadRange(ITextRange range, ITextCharacterFormat format) { var startPosition = range.StartPosition; var endPosition = range.EndPosition + 1; var clone = range.GetClone(); clone.Collapse(true); clone.SetText(TextSetOptions.Unhide, "\u200B"); clone.CharacterFormat.SetClone(format); clone.SetRange(endPosition, endPosition); clone.SetText(TextSetOptions.Unhide, "\u200B"); clone.CharacterFormat.SetClone(format); range.SetRange(startPosition, endPosition + 1); }
/// <summary> /// Try getting the token associated with a text range. /// </summary> /// <param name="range">The range of the token to get.</param> /// <param name="token">When this method returns, contains the token associated with the specified range; otherwise, it is null.</param> /// <returns>true if there is a token associated with the text range; otherwise false.</returns> public bool TryGetTokenFromRange(ITextRange range, out RichSuggestToken token) { token = null; range = range.GetClone(); if (range != null && !string.IsNullOrEmpty(range.Link)) { lock (_tokensLock) { return(_tokens.TryGetValue(range.Link, out token)); } } return(false); }
// 高亮显示用户搜索的字符 private void btnSearch_Click(object sender, RoutedEventArgs e) { // 清除高亮字符的高亮效果 ITextCharacterFormat charFormat; for (int i = 0; i < _highlightedWords.Count; i++) { charFormat = _highlightedWords[i].CharacterFormat; charFormat.BackgroundColor = Colors.Transparent; _highlightedWords[i].CharacterFormat = charFormat; } _highlightedWords.Clear(); // 获取全部文本,并将操作点移动到文本的起点 ITextRange searchRange = txtEditor.Document.GetRange(0, TextConstants.MaxUnitCount); searchRange.Move(0, 0); bool textFound = true; do { // 在全部文本中搜索指定的字符串 if (searchRange.FindText(txtSearch.Text, TextConstants.MaxUnitCount, FindOptions.None) < 1) { textFound = false; } else { _highlightedWords.Add(searchRange.GetClone()); // 实体化一个 ITextCharacterFormat,指定字符背景颜色为黄色 ITextCharacterFormat charFormatting = searchRange.CharacterFormat; charFormatting.BackgroundColor = Colors.Orange; // 设置指定文本的字符格式(高亮效果) searchRange.CharacterFormat = charFormatting; } } while (textFound); }
private async Task ShowCompletionListAsync() { if (ViewModel.CodeEditor is null) { return; } ITextRange range = CodeEditor.Document.Selection; if (range.Length < 0) { range.EndPosition = range.StartPosition; } else { range.StartPosition = range.EndPosition; } TextSpan selectionSpan = GetAdjustedTextSpan(TextSpan.FromBounds(range.StartPosition, range.EndPosition), ViewModel.CurrentText, ViewModel.NewLineMode, true); CompletionList?completionList = await ViewModel.GetCompletionListAsync(selectionSpan.Start); if (completionList != null) { bool expandsToWord = true; ITextRange wordRange = range.GetClone(); if (wordRange.Character == '\r') { ITextRange wordRangeClone = range.GetClone(); wordRangeClone.Move(TextRangeUnit.Word, -1); expandsToWord = IsValidCSharpIdentifierCharacter(wordRangeClone.Character); } if (expandsToWord) { wordRange.Move(TextRangeUnit.Word, -1); wordRange.MoveEnd(TextRangeUnit.Word, 1); } string word = wordRange.Text.Trim(); var completionItems = ViewModel.FilterCompletionItems(completionList.Items, word); CompletionListFlyout.Items.Clear(); foreach (CompletionItem item in completionItems) { var properties = item.Properties; if (properties.TryGetValue("SymbolName", out string symbolName)) { MenuFlyoutItem menuFlyoutItem = new MenuFlyoutItem { Text = symbolName }; menuFlyoutItem.Click += async(s, e) => { CompletionChange?completionChange = await ViewModel.GetCompletionChangeAsync(item); if (completionChange != null) { TextSpan span = GetAdjustedTextSpan(completionChange.TextChange.Span, ViewModel.CurrentText, ViewModel.NewLineMode); CodeEditor.Document.Selection.StartPosition = span.Start; CodeEditor.Document.Selection.EndPosition = span.End; CodeEditor.Document.Selection.TypeText(completionChange.TextChange.NewText); } }; CompletionListFlyout.Items.Add(menuFlyoutItem); } } if (CompletionListFlyout.Items.Count > 0) { Point flyoutPosition = GetAdjustedPointFromDocument(range); flyoutPosition = new Point(flyoutPosition.X + 12, flyoutPosition.Y + 8); CompletionListFlyout.ShowAt(CodeEditor, new FlyoutShowOptions { Position = flyoutPosition, ShowMode = FlyoutShowMode.Transient }); return; } } CompletionListFlyout.Hide(); }