コード例 #1
0
        /// <summary>
        /// Highlights the symbol node corresponding to the current caret position in the editor, expands/collapses nodes, then updates the UI.
        /// </summary>
        private async ValueTask HighlightExpandAndPresentItemsAsync(ImmutableSegmentedList <ExpansionOption> expansionOption, CancellationToken cancellationToken)
        {
            var model = await _filterAndSortDataModelQueue.WaitUntilCurrentBatchCompletesAsync().ConfigureAwait(false);

            if (model is null)
            {
                return;
            }

            // Switch to the UI thread to get the current caret point and latest active text view then create the UI model.
            await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            var activeTextView = GetLastActiveIWpfTextView();

            if (activeTextView is null)
            {
                return;
            }

            var caretPoint = activeTextView.GetCaretPoint(activeTextView.TextBuffer);

            if (!caretPoint.HasValue)
            {
                return;
            }

            var documentSymbolUIItems = DocumentOutlineHelper.GetDocumentSymbolUIItems(model.DocumentSymbolData, _threadingContext);

            // Switch to the threadpool to determine which node to select (if applicable).
            await TaskScheduler.Default;

            var symbolToSelect = DocumentOutlineHelper.GetDocumentNodeToSelect(documentSymbolUIItems, model.OriginalSnapshot, caretPoint.Value);

            // Switch to the UI thread to update the view.
            await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            // Expand/collapse nodes based on the given Expansion Option.
            var expansion = expansionOption.Last();

            if (expansion is not ExpansionOption.NoChange && SymbolTree.ItemsSource is not null)
            {
                DocumentOutlineHelper.SetIsExpanded(documentSymbolUIItems, (IEnumerable <DocumentSymbolUIItem>)SymbolTree.ItemsSource, expansion);
            }

            // Hightlight the selected node if it exists, otherwise unselect all nodes (required so that the view does not select a node by default).
            if (symbolToSelect is not null)
            {
                // Expand all ancestors first to ensure the selected node will be visible.
                DocumentOutlineHelper.ExpandAncestors(documentSymbolUIItems, symbolToSelect.RangeSpan);
                symbolToSelect.IsSelected = true;
            }
            else
            {
                // On Document Outline Control initialization, SymbolTree.ItemsSource is null
                if (SymbolTree.ItemsSource is not null)
                {
                    DocumentOutlineHelper.UnselectAll((IEnumerable <DocumentSymbolUIItem>)SymbolTree.ItemsSource);
                }
            }

            SymbolTree.ItemsSource = documentSymbolUIItems;
        }