我将一个非常庞大的项目集合绑定到ItemsControl。 ItemsControl的ItemTemplate设置为呈现数据的自定义用户控件。 ItemControl已虚拟化。
现在的问题是ItemsControl中的每个用户控件都会变得非常高。甚至可能它变得比实际的屏幕高度更高。如果发生这种情况我就没有机会看到其余的用户控件,因为只要我滚动集合中的下一个项目就会被带到屏幕的顶部,并且只有一半显示的项目会完全滚动到视图之外。如果我不使用虚拟化,一切都显然正常。
有没有办法绕过这种行为并仍能使用虚拟化?
答案 0 :(得分:1)
您的ItemsControl的ScrollViewer是否具有内容滚动设置?
编辑2:正如Dan所说,只要你试图顺利滚动就会出现,你就会失去虚拟化。我不确定您的要求是什么,但潜在的解决方法可能类似于以下内容:
<Window x:Class="TestApp11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:l="clr-namespace:TestApp11"
Title="Window1" Height="200" Width="200">
<Grid>
<ItemsControl>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type ListBoxItem}">
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="160">
<Border Height="200" Width="140" BorderBrush="Red" BorderThickness="10" Margin="1" Background="Blue" />
</ScrollViewer>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingStackPanel.VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
<ContentElement />
</ItemsControl>
</Grid>
</Window>
基本上,您可以让ItemTemplate将您的UserControl项包装在ScrollViewer中。我没有在我的示例中显示它,但是您可以将ScrollViewer的MaxHeight(在ItemTemplate内)绑定到可视区域的高度,然后只有当UserControl太大而不能显示时,垂直滚动条才会显示适合屏幕。
我可以看到这可能是一个太难看的解决方案给客户,但在这种情况下,我认为唯一的选择是走丹建议的路线。
答案 1 :(得分:1)
这种行为有一种方法,但它并不完全相当......基本上,它是实现自己的虚拟化面板。正如您所注意到的,内置面板的行为是从最顶层项目的顶部绘制 - 您不能在屏幕顶部有半个项目。这基本上是因为它使虚拟化代码的重量更轻,而且在大多数情况下它不是问题。
您可以创建自己的面板(源自VirtualizingPanel
),但没有此限制。这不是直截了当的,但结果是值得的!
在您的情况下,如果所有项目都是固定大小且超出屏幕大小,您可能会发现它并不那么复杂 - 当项目变量大小时会出现很多复杂性