Reputation: 889
I'm using an itemscontrol to hold a number of controls of varying size. I decided to enable virtualizing due to the number of controls I need to display (it was taking a second or so to "Load" the control in some cases, and I really need to display them in a long list as opposed to using some kind of collapsing).
Below is a simple test for what I have (I'm using the reflection hack mentioned here). The problem is that the thumb on the vertical scrollbar updates as you drag, which I guess makes sense due to the fact that the scrollviewer itself is updating on the fly as new controls come into view, but I was wondering if there is a solution?
Is it possible to have virtualizing, pixel-based scrolling and a thumb whose size reflects ALL the controls and not just the ones its processed?
public class A { public double Height { get; set; } };
public partial class MainWindow : Window
{
public List<A> Data { get; set; }
public MainWindow()
{
var r = new Random();
Data = new List<A>();
for (int i = 0; i < 250; ++i)
{
Data.Add(new A() { Height = r.Next(10, 500) });
}
DataContext = this;
InitializeComponent();
}
}
<ItemsControl ItemsSource="{Binding Data}" VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel local:PixelBasedScrollingBehavior.IsEnabled="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<UniformGrid Columns="4">
<Label Content="label" Height="{Binding Height}"/>
<TextBox />
<UniformGrid Rows="2">
<Button />
<Button />
</UniformGrid>
<Slider/>
</UniformGrid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
As a secondary question. To see what was taking so long when virtualizing was disabled, I derived from StackPanel, and timed the Measure/Arrange functions and found all the Load time to be pretty much spent in those functions. In my case, 600ms in Measure and 200ms in Arrange. The WPF profiling tools also point to layout being the killer. This seems like an awfully long time. Admittedly, rendering 250 controls (10k elements according to Snoop)like this isn't something you most likely want to do, but can anyone shed some light into why it takes so long? Is the whole layout updated whenever a new control is created? I've had a play with some custom templates for the Slider control to try and reduce the number for elements it uses with some success, but then I lose functionality.
Upvotes: 2
Views: 606