C# 滚动多个虚拟化项控件
我有一个类似日历的控件,一周中的每一天都有一列和七个可观察的集合,每个集合最多可以包含100个或更多项 我希望能够在虚拟化它们的同时垂直滚动它们[Edit] 现在我有以下的布局C# 滚动多个虚拟化项控件,c#,wpf,C#,Wpf,我有一个类似日历的控件,一周中的每一天都有一列和七个可观察的集合,每个集合最多可以包含100个或更多项 我希望能够在虚拟化它们的同时垂直滚动它们[Edit] 现在我有以下的布局 <ScrollViewer> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"></ColumnDefinition>
<ScrollViewer>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Monday -->
<Border Grid.Column="0">
<ItemsControl ItemsSource="{Binding Monday}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling" ... />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<MyControl Item="{Binding}" ... />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
...
</Grid>
</ScrollViewer>
...
然而,性能是有问题的,我认为这是因为ScrollViewer允许网格->边框->虚拟化StackPanel垂直扩展,而不是虚拟化。是这样吗
(旁注:我已尝试删除ScrollViewer并将CanVerticallyScroll=“True”添加到VirtualzingStackPanels,并希望它们独立滚动以检查性能是否更好,但它们根本不会滚动)
什么是正确的布局
编辑:每列显示100个元素(总共700个)需要13秒,滚动实际上是可以的
[Edit2]:
由于需要同时滚动,我尝试创建一个包含“一行”(7项)的新集合,并将其作为listview中的模板。可怕的结果[/Edit2]要使ItemsControl虚拟化,您不仅需要使用VirtualzingStackPanel,还需要将ScrollViewer添加到ItemsControl的模板中(通常ItemsControl没有ScrollViewer) 将此模板添加到ItemsControl中:
<ItemsControl.Template>
<ControlTemplate>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ScrollViewer Padding="{TemplateBinding Control.Padding}"
Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
作为一种不同的解决方案,您当然可以用ListBox替换ItemsControl,它已经具备了虚拟化列表所需的所有功能。解决此问题的方法是在ScrollViewer中不使用一个虚拟化ItemsControl呈现七列(这似乎扩展了ItemsControl并使其绘制所有控件),但使用一个ItemsControl进行渲染,解决了在ItemsControl.Template中滚动的问题,并一次显示一行 我创建了一个新集合,并“每行”抓取对象
for(int PI=0;PIPI?Monday[PI]:空,
星期二。计数>π?星期二[π]:空,
星期三.计数>PI?星期三[PI]:空,
星期四.Count>PI?星期四[PI]:空,
Friday.Count>PI?Friday[PI]:空,
星期六.计数>圆周率?星期六[圆周率]:空,
Sunday.Count>PI?Sunday[PI]:空
));
}
并使用此
<ItemsControl ItemsSource="{Binding Presentation}" VirtualizingPanel.ScrollUnit="Pixel">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True" Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel
Orientation="Vertical"
IsVirtualizing="True"
VirtualizationMode="Recycling">
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<MyControl Item="{Binding Monday}" Grid.Column="0" ... />
...
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate
</ItemsControl>
...
希望您有充分的理由使用自定义控件,通常您可以使用DataTemplate
来代替。我认为延迟可能是由于复杂的模板造成的,但我们看不到这一点,所以这只是一个猜测。@XAMlMAX感谢您的输入!基本上是因为该控件可能在其他地方被重用。pu的好处可能在哪里它的内容是否直接在datatemplate中?理想情况下,您可以在资源字典中将其定义为静态资源,然后在您需要的地方在xaml中引用它。App.xaml将是一个完美的起点。我会检查这是否有可能,但我在它后面有540行代码。您是指C#
code还是JUxaml?如果你有代码隐藏,那么可能有一个很好的理由,出于好奇,为什么你有代码隐藏?谢谢!这个例子中的VirtualzingStackPanel在哪里?这会导致列独立滚动,而不是同时滚动,对吗?这不是全部代码,只是你需要在it中添加的部分emsControl。是的,这将使每个列独立滚动。好的,谢谢,很遗憾这不是我想要实现的,同时滚动是必须的。我想我可以让其他人跟随,但他们会在最后停止,而其他人继续滚动
<ItemsControl ItemsSource="{Binding Presentation}" VirtualizingPanel.ScrollUnit="Pixel">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True" Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel
Orientation="Vertical"
IsVirtualizing="True"
VirtualizationMode="Recycling">
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<MyControl Item="{Binding Monday}" Grid.Column="0" ... />
...
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate
</ItemsControl>