我有一个类似日历的控件,每周的每一天都有一个列和7个ObservableCollections,每个条目最多可以包含100项或更多项。
我希望能够垂直滚动它们,编辑,,同时/Edit,同时让它们虚拟化。
现在我有了下面的布局
<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允许网格->边界-> VirtualizingStackPanel垂直扩展而不是虚拟化。是这样吗?
(Sidenote:我尝试删除ScrollViewer并将CanVerticallyScroll="True“添加到VirtualizingStackPanels中,并希望它们独立滚动以检查性能是否更好,但它们根本不会滚动)
什么才是正确的布局呢?
编辑:显示每列100个元素(总共700个)需要13秒,滚动实际上是可以的
Edit2:由于所需的模拟滚动,我尝试创建一个包含“一行”(7项)的新集合,并将其作为列表视图中的模板。可怕的结果/Edit2
发布于 2018-11-16 15:04:59
该问题的解决方案是,不呈现七列,每个列在一个ScrollViewer中使用一个虚拟化的ScrollViewer(这似乎扩展了ItemsControls并使它们绘制所有控件),而是使用一个ItemsControl呈现,解决了在ItemsControl.Template中滚动的问题,并一次显示一个行。
我创建了一个新的集合,并抓取“每一行”的对象。
for(int PI = 0; PI < MathHelper.Max(Monday.Count, Tuesday.Count, Wednesday.Count, Thursday.Count, Friday.Count, Saturday.Count, Sunday.Count); PI++)
{
Presentation.Add(new WeekRow(
Monday.Count > PI ? Monday[PI] : null,
Tuesday.Count > PI ? Tuesday[PI] : null,
Wednesday.Count > PI ? Wednesday[PI] : null,
Thursday.Count > PI ? Thursday[PI] : null,
Friday.Count > PI ? Friday[PI] : null,
Saturday.Count > PI ? Saturday[PI] : null,
Sunday.Count > PI ? Sunday[PI] : null
));
}并使用以下方法显示它们
<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>这里真正重要的是将ScrollViewer的CanContentScroll属性设置为true,否则虚拟化将无法工作(谁知道为什么)。这一点在马克的回答中缺失了。
编辑:同样值得一提的是,要获得“平滑滚动”(就像wpf可以获得的“平滑”一样),必须将VirtualizingPanel.ScrollUnit设置为"Pixel“。但是它只在设置为ItemsControl、而不是到ScrollViewer、ItemsPresenter或VirtualizingStackPanel本身时才能工作。不管出于什么原因。
https://stackoverflow.com/questions/53319414
复制相似问题