private void CreateSingleEdit(Action editAction) { _ignoreChange = true; editAction.Invoke(); TextDocument.EndUndoGroup(); TextDocument.BeginUndoGroup(); _ignoreChange = false; }
private void RichEditBox_TextChanging(RichEditBox sender, RichEditBoxTextChangingEventArgs args) { if (_ignoreChange || !args.IsContentChanging) { return; } _ignoreChange = true; ValidateTokensInDocument(); TextDocument.EndUndoGroup(); TextDocument.BeginUndoGroup(); _ignoreChange = false; }
internal async Task CommitSuggestionAsync(object selectedItem) { var currentQuery = _currentQuery; var range = currentQuery?.Range.GetClone(); var id = Guid.NewGuid(); var prefix = currentQuery?.Prefix; var query = currentQuery?.QueryText; // range has length of 0 at the end of the commit. // Checking length == 0 to avoid committing twice. if (prefix == null || query == null || range == null || range.Length == 0) { return; } var textBefore = range.Text; var format = CreateTokenFormat(range); var eventArgs = new SuggestionChosenEventArgs { Id = id, Prefix = prefix, QueryText = query, SelectedItem = selectedItem, DisplayText = query, Format = format }; if (SuggestionChosen != null) { await SuggestionChosen.InvokeAsync(this, eventArgs); } var text = eventArgs.DisplayText; // Since this operation is async, the document may have changed at this point. // Double check if the range still has the expected query. if (string.IsNullOrEmpty(text) || textBefore != range.Text || !TryExtractQueryFromRange(range, out var testPrefix, out var testQuery) || testPrefix != prefix || testQuery != query) { return; } lock (_tokensLock) { var displayText = prefix + text; _ignoreChange = true; var committed = TryCommitSuggestionIntoDocument(range, displayText, id, eventArgs.Format ?? format); TextDocument.EndUndoGroup(); TextDocument.BeginUndoGroup(); _ignoreChange = false; if (committed) { var token = new RichSuggestToken(id, displayText) { Active = true, Item = selectedItem }; token.UpdateTextRange(range); _tokens.TryAdd(range.Link, token); } } }