gpt4 book ai didi

c# - 在虚拟化 WPF TreeView 中滚动非常不稳定

转载 作者:IT王子 更新时间:2023-10-29 04:05:14 24 4
gpt4 key购买 nike

如果在 TreeView 中启用了具有不同大小的项目的虚拟化,则会出现多个问题:

  • 垂直滚动条会随机更改其大小,并且在查看整个树后不会记住元素的大小。用鼠标滚动很难。

  • 在一些上下滚动之后,ArgumentNullException 从框架代码中抛出。

重现很简单:创建一个新的 WPF 应用程序,然后将此代码放入 MainWindow.xaml

<Window x:Class="VirtualTreeView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="800" Width="400" Left="0" Top="0"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<TreeView x:Name="tvwItems" ItemsSource="{Binding Items}"
VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
<TreeView.ItemTemplate>
<DataTemplate>
<Border Height="{Binding Height}" Width="{Binding Height}"
BorderThickness="1" Background="DarkGray" BorderBrush="DarkBlue"/>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Window>

并将此代码放入 MainWindow.xaml.cs

using System.Collections.ObjectModel;
using System.Linq;

namespace VirtualTreeView
{
public partial class MainWindow
{
public ObservableCollection<Item> Items { get; set; }

public MainWindow ()
{
Items = new ObservableCollection<Item>(Enumerable.Range(0, 20).Select(i => new Item {
Height = i*20,
}));
InitializeComponent();
}
}

public class Item
{
public double Height { get; set; }
}
}

当应用程序运行时,将鼠标光标移动到 TreeView 中,使用鼠标滚轮滚动到底部,然后滚动到顶部,然后再次开始向下滚动。在中间某处抛出以下异常:

System.ArgumentNullException was unhandled
HResult=-2147467261
Message=Value cannot be null.
Parameter name: element
Source=PresentationCore
ParamName=element
StackTrace:
at MS.Internal.Media.VisualTreeUtils.AsNonNullVisual(DependencyObject element, Visual& visual, Visual3D& visual3D)
at System.Windows.Media.VisualTreeHelper.GetParent(DependencyObject reference)
at System.Windows.Controls.VirtualizingStackPanel.FindScrollOffset(Visual v)
at System.Windows.Controls.VirtualizingStackPanel.OnAnchorOperation(Boolean isAnchorOperationPending)
at System.Windows.Controls.VirtualizingStackPanel.OnAnchorOperation()
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at VirtualTreeView.App.Main() in d:\Docs\Projects\_Try\VirtualTreeView\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

您还可以看到异常并不是唯一的问题。上下滚动时,滚动条不断改变大小。 (同样的问题没有出现在ListBox中,它无法预测大小,但在查看整个列表后会记住总高度。)

问题:如何让滚动条正常运行并消除异常? (我不介意指向替代 TreeView 控件的链接,或者可能支持这种情况的虚拟化面板。)

最佳答案

为了使链接更加突出,我也将其发布在答案中。看起来框架代码中有一个错误,目前还没有找到解决方法。我已经在 Microsoft Connect 上报告了该错误:

Microsoft Connect: Scrolling in virtualized WPF TreeView is very unstable

@sixlettervariables 在评论中发布了一个可能相关的错误:

Microsoft Connect: WPF application freezes while scrolling the TreeView under specific conditions

如果您可以重现这些错误,请给它们投票。

关于c# - 在虚拟化 WPF TreeView 中滚动非常不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14092691/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com