From e65a99015b4811ade69d7ce12d08ab6f7ec60e2f Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Fri, 17 May 2024 17:01:26 -0500 Subject: [PATCH] Work around dotnet/wpf#122 in Document Outline --- .../DocumentOutline/DocumentOutlineView.xaml | 12 ++--- .../DocumentOutline/VirtualizingTreeView.cs | 49 +++++++++++++++++++ 2 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 src/VisualStudio/Core/Def/DocumentOutline/VirtualizingTreeView.cs diff --git a/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml b/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml index eed308a9348ad..4cff00aaa9311 100644 --- a/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml +++ b/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml @@ -77,10 +77,6 @@ - - - + diff --git a/src/VisualStudio/Core/Def/DocumentOutline/VirtualizingTreeView.cs b/src/VisualStudio/Core/Def/DocumentOutline/VirtualizingTreeView.cs new file mode 100644 index 0000000000000..cebae0913d1dc --- /dev/null +++ b/src/VisualStudio/Core/Def/DocumentOutline/VirtualizingTreeView.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Windows.Automation.Peers; +using System.Windows.Controls; + +namespace Microsoft.VisualStudio.LanguageServices.DocumentOutline; + +// Provide a workaround for https://github.com/dotnet/wpf/issues/122 when using virtualized TreeView. +internal sealed class VirtualizingTreeView : TreeView +{ + public VirtualizingTreeView() + { + // Two important properties are being set for TreeView: + // We set IsVirtualizing to "true" so that WPF only generates internal data-structures elements that are visible. + // Setting VirtualizationMode to "Recycling" ensures that WPF internal data is reused as items scroll in and out of view. + VirtualizingPanel.SetIsVirtualizing(this, true); + VirtualizingPanel.SetVirtualizationMode(this, VirtualizationMode.Recycling); + } + + protected override AutomationPeer OnCreateAutomationPeer() + => new VirtualizingTreeViewAutomationPeer(this); + + public sealed class VirtualizingTreeViewAutomationPeer(TreeView owner) + : TreeViewAutomationPeer(owner) + { + protected override ItemAutomationPeer CreateItemAutomationPeer(object item) + => new VirtualizingTreeViewDataItemAutomationPeer(item, this, null); + } + + public sealed class VirtualizingTreeViewDataItemAutomationPeer(object item, ItemsControlAutomationPeer itemsControlAutomationPeer, TreeViewDataItemAutomationPeer? parentDataItemAutomationPeer) + : TreeViewDataItemAutomationPeer(item, itemsControlAutomationPeer, parentDataItemAutomationPeer) + { + protected override string GetNameCore() + { + try + { + return base.GetNameCore(); + } + catch (NullReferenceException) + { + // https://github.com/dotnet/wpf/issues/122 + return ""; + } + } + } +}