Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I virtualize a "datagrid like" Control Horizontally and Vertically on XAML/C# (Windows 8.1 - WinRT)

Problem

I'm trying to create a "datagrid like" control on a Universal App (WinRT).
This control has to show lots of elements (Cells) but only has a small View-area, so it's a perfect candidate for Virtualization, which it definitely needs.

How can I have Virtualization both Horizontally and Vertically for such a thing?

example "table like" control with a View Area

What I tried (One-Direction Virtualization)

I have tried using both the ListView, GridView and ItemsControl. I obviously managed to have Only Vertically or Only Horizontally Virtualization with those.

The most important thing I had to do to achieve One-Direction Virtualization and have it look like a table was changing the ItemsPanel of any of those (ListView/GridView/ItemsControl) to something like this:

<ScrollViewer           
       VerticalScrollBarVisibility="Auto" 
       HorizontalScrollBarVisibility="Auto" 
       HorizontalScrollMode ="Auto"
       VerticalScrollMode ="Auto"
       ZoomMode="Disabled"
       ViewChanged="DataGridView_OnViewChanged"
       Width="700">
    <ItemsControl 
            VerticalAlignment="Top"
            HorizontalAlignment="Left"
            ItemsSource="{Binding Cells}"
            Width="{Binding DataGridWidth}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <ItemsWrapGrid MaximumRowsOrColumns="{Binding NumberOfColumns}"
                            VirtualizingStackPanel.VirtualizationMode="Recycling"
                            ItemWidth="{Binding CellWidth}"
                            ItemHeight="{Binding CellHeight}"
                            CacheLength="2.0"
                            VerticalAlignment="Top" 
                            HorizontalAlignment="Left" 
                            Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        ...
    </ItemsControl>
</ScrollViewer>

Note: "VirtualizingStackPanel.VirtualizationMode" and "CacheLenght" are not really necessary in there. But notice that I'm setting the Width on the ScrollViewer and the ItemsControl. I think that's the culprit in making this Virtualized only in one direction. Because I'm giving the ItemsControl enough room to display the items. Problem is, it's the only way to make the MaximumRowsOrColumns work and achieve a "DataGrid like" control.

This solution starts becoming sluggish/broken at roughly 100 x 100 elements because even if it's only displaying 10 rows, it's still 10x100 Cells to draw.

The Cells all have the same look and feel and therefore share the same DataTemplate which should help getting a solution.

I can use any Control, I only mentioned ListView, GridView and ItemsControl because they were the ones more obvious to me (to solve this problem).

Any ideas on how to achieve Two-Direction (Horizontal and Vertical) Virtualization with a "DataGrid like" control on Windows Universal Apps with XAML/C#?

Note 2: WPF solutions likely won't work with WinRT XAML/C#. Please check that before posting a WPF solution.

like image 706
Dinis Vieira Avatar asked Apr 01 '15 18:04

Dinis Vieira


1 Answers

I haven't done this, but found a few interesting articles:

1) Your grid is located in the ScrollViewer, how about trying to use attached propery like VirtualizingStackPanel.VirtualizationMode?

Link: https://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.virtualizationmode%28v=vs.110%29.aspx

2) If previous doesn't work for you, i guess you can write your own virtualization mechanism by using Incremental virtualization article ( i really think they can be used for this ).

Link: https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh780657.aspx

like image 90
Cheese Avatar answered Sep 23 '22 23:09

Cheese