gpt4 book ai didi

带有 ListBox 的 WPF ListBox - UI 虚拟化和滚动

转载 作者:行者123 更新时间:2023-12-03 01:46:37 27 4
gpt4 key购买 nike

我的原型(prototype)显示包含“页面”的“文档”由缩略图表示。每个文档可以有任意数量的页面。例如,可能有1000 个文档,每个文档 5 页,或 5 个文档,每个文档 1000 页每个,或介于两者之间。文档不包含其他文档。在我的 xaml 标记中,我有一个 ListBox,其 ItemsTemplate引用一个也有一个ListBox 的innerItemsTemplate。我想要2 个级别的所选项目,以便我可以执行各种操作在文档或页面上(删除、合并、移动到新位置等)。innerItemsTemplate ListBox 使用 WrapPanel 作为 ItemsPanelTemplate

对于我有大量文档但只有少数文档的场景每页(例如,10000 个文档,每页 5 页),滚动得益于 VirtualizingStackPanel 的 UI 虚拟化,效果非常好。但是,如果我有大量页面,我就会遇到问题。一个文件1000 页一次只会显示大约 50 页(无论屏幕适合什么),当我向下滚动时,外部 ListBox 移动到下一个文档,跳过 950页面或不可见的页面。除此之外,没有VirtualzingWrapPanel 因此应用程序内存确实增加了。

我想知道我是否以正确的方式处理这件事,尤其是因为这有点难以解释!我希望能够显示10000 个文档,每个文档 1000 页(仅显示屏幕上适合的内容),使用 UI 虚拟化,并且还可以平滑滚动。

如何确保滚动移动到文档中的所有页面在显示下一个文档之前,仍然保持UI虚拟化?滚动条似乎只移动到下一个文档。

表示“文档”和“页面”似乎合乎逻辑吗?我当前在 ListBox 中使用 ListBox 的方法?

我非常感谢您的任何想法。谢谢。

最佳答案

如果您准备使用反射来访问 VirtualizingStackPanel 的私有(private)功能,则可以在 WPF 4.0 中实现平滑滚动 VirtualizingStackPanel,而无需牺牲虚拟化。您所要做的就是将 VirtualizingStackPanel 的私有(private) IsPixelBased 属性设置为 true。

请注意,在 .Net 4.5 中,不需要此 hack,因为您可以设置 VirtualizingPanel.ScrollUnit="Pixel"。

为了使它变得非常简单,这里有一些代码:

public static class PixelBasedScrollingBehavior 
{
public static bool GetIsEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}

public static void SetIsEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}

public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(PixelBasedScrollingBehavior), new UIPropertyMetadata(false, HandleIsEnabledChanged));

private static void HandleIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var vsp = d as VirtualizingStackPanel;
if (vsp == null)
{
return;
}

var property = typeof(VirtualizingStackPanel).GetProperty("IsPixelBased",
BindingFlags.NonPublic | BindingFlags.Instance);

if (property == null)
{
throw new InvalidOperationException("Pixel-based scrolling behaviour hack no longer works!");
}

if ((bool)e.NewValue == true)
{
property.SetValue(vsp, true, new object[0]);
}
else
{
property.SetValue(vsp, false, new object[0]);
}
}
}

例如,要在列表框中使用它,您可以这样做:

<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel PixelBasedScrollingBehavior.IsEnabled="True">
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>

关于带有 ListBox 的 WPF ListBox - UI 虚拟化和滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1977929/

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