Windows Phone Features For the VirtualizingPanel
Join the DZone community and get the full member experience.
Join For FreeThe VirtualizingPanel comes with new features in WPF 4.5: two properties named ScrollUnit and CacheLength and virtualization on grouped data. In this post we will discover them in details.
This post is a part of a serie on WPF 4.5 new features.
WPF 4.0 behavior
To illustrate the new properties and their usage, we will create a demo project. It can be found on my Dropbox folder after registration.
This simple WPF application display a list of persons in a listbox with virtualization enabled. In the last part, we will group the persons by age.
A button is here to allow the user to add a lot of persons to the list (500 actually). When this operation is done, we calculate the elapsed render time and display it as a status bar message. This allow us to be sure that virtualization is really enabled. When it is, the load takes a dozen of ms and when it’s not, the operation takes a lot of time (7000 ms on my computer). This is one of the scenarii addressed by the virtualization.
foreach (var person in persons) { Persons.Add(person); } var watch = new Stopwatch(); watch.Start(); //Wait for the rendering is finished.. Dispatcher.CurrentDispatcher.Invoke(new Action(() => { }), DispatcherPriority.Loaded, null); watch.Stop(); Message = string.Format("Rendering took {0} ms.", watch.ElapsedMilliseconds);
Virtualization can be enabled and disabled via the VirtualizingStackPanel.IsVirtualizing attached property on a ListBox. By default it is but we force it anyway:
<ListBox ItemsSource="{Binding Persons}" Background="LightBlue" ItemTemplate="{StaticResource PersonDataTemplate}" ItemContainerStyle="{StaticResource ListBoxItemStyle}" VirtualizingStackPanel.IsVirtualizing="True" HorizontalContentAlignment="Stretch" />
To be able to see things clearly, I defined a style for the
ListBoxItem which set their background to pink and I set the ListBox’s
Background to blue:
CacheLength
The ViewPort is the visible aera of the virtualizing panel. With virtualization, only visible inside the viewport are really created in memory. Creating this items can be intensive and requires a noticeable time to be done. If so, the scrolling experience is not very good for the user because the reactivness of the application falls to nothing.
To reproduce this scenario, I have create an UserControl named TimeConsumingControl and I do something long in its constructor. Then I put it in the DataTemplate:
<DataTemplate x:Key="PersonDataTemplate" DataType="{x:Type local:Person}"> <Grid> <!--This will take time to be instancied--> <local:TimeConsumingControl /> <!--Rest of the data template--> ... </Grid>
In WPF 4.5 you can create a Cache of the item not displayed. When the virtualizing panel has finished the render of its items, it start the creation of the cache with a low priority. By doing so, when the user scroll into the list, he’ll not feel the slowness of the rendering because the items will already be created in the cache. Not that it’ll be true only for the one in the cache.
You can use two properties to configure the cache in WPF 4.5:
- CacheLength : The amount of space created in the cache before and after the ViewPort. The default value is 1,1.
- CacheLengthUnit : the unit of the ammount of space: Pixel, Item or Page. A page is defined by the size of the viewort. The default value is Page in the MSDN doc but it seems to be Item in my tests.
To demonstrate the benefit of their use is hard to do with a picture, but you can try the demo application to notice it.
Here is an example of their use in the the demo application XAML which define a cache of 2 pages before the viewPort and 3 after it:
<ListBox ItemsSource="{Binding Persons}" ItemTemplate="{StaticResource PersonDataTemplate}" ItemContainerStyle="{StaticResource ListBoxItemStyle}" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.CacheLength="2,3" VirtualizingStackPanel.CacheLengthUnit="Page"/>
ScrollUnit
When virtualization is enabled, the scrolling can be perceived as
little odd by the user because only full items are displayed. If an item
does not fit entirely in the viewport defined by the ItemsControl then
it’s not displayed.
In WPF 4.5, you can set the ScrollUnit property to one of these following values:
- Item : The virtualizing panel can display blank aera because items that would require to be crop are not displayed. This is the default value (as in WPF 4.0).
- Pixel : The virtualizing panel can display partial / cropped items as you may excepted it to be the default behavior.
So if we update the previous example to set this property to Pixel we’ll get the following XAML:
<ListBox ItemsSource="{Binding Persons}" ItemTemplate="{StaticResource PersonDataTemplate}" ItemContainerStyle="{StaticResource ListBoxItemStyle}" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.ScrollUnit="Pixel" />
IsContainerVirtualizable
Finally, I found out reading the MSDN documentation a new attached property named IsContainerVirtualizable. It’s seems to be a property which tells the VirtualizingPanel if it should virtualize an item or not.
I tried to use it but I didn’t managed to. So I can’t tell you more on this except that it exist!
Opinions expressed by DZone contributors are their own.
Trending
-
Avoiding Pitfalls With Java Optional: Common Mistakes and How To Fix Them [Video]
-
An Overview of Kubernetes Security Projects at KubeCon Europe 2023
-
What Is Istio Service Mesh?
-
VPN Architecture for Internal Networks
Comments