-1

I have a long page with a ScrollViewer (like web-page).

Page contains header and list of lazy loading infinite scrolling content. Header should scroll away with list content. Header height is 5 times larger than list item height.

Is there any good way to virtualize this?

<ScrollViewer>
    <StackPanel>
        <TextBlock Text="Header:" />
        <StackPanel Orientation="Horizontal" Height="500">
            <!--Complex UI-->
        </StackPanel>

        <TextBlock Text="Videos:"/>
        <ItemsControl ItemsSource="{Binding Videos}" 
                      ItemsTemplate="{StaticResource VideoDataTemplate}" />
    </StackPanel>
</ScrollViewer>

What I've tried:

  1. Make DataTemplateSelector for header/list item and put everything into one ItemsControl. Reason: ScrollViewer with CanContentScroll="True" scrolls header away on first scroll tick. This is not acceptable because header is too large.
  2. Make two ScrollViewers. One for header with large bottom margin, one for items with header height top margin. Reason: Too hard to sync top offset and mouse events.
Mikolaytis
  • 921
  • 1
  • 12
  • 27
  • 1
    What if you set the VirtualizingPanel.ScrollUnit property of the ItemsControl to Pixel and use the first approach? – mm8 Sep 01 '17 at 10:52
  • I've created an empty project with that solution. Turn's out it's super unstable and crashes on scroll down a bit. Looks like it's because items have different height. Here is gist: https://gist.github.com/Mikolaytis/82e739aa6adaea328d5369bf3132f016 – Mikolaytis Sep 01 '17 at 11:08
  • I've sayed that i've created an empty project! I've attached link to gist. I've attached crash details in gist comment. You can create empty project and copy gist code into it, try it. Or download project from here and test it: https://drive.google.com/open?id=0B38_Y0INL95-NzFEejk1Vi1LV2s – Mikolaytis Sep 01 '17 at 11:52
  • This seems very similar to this bug: https://connect.microsoft.com/VisualStudio/feedback/details/789438/scrolling-in-virtualized-wpf-treeview-is-very-unstable. It should have been fixed though but I can reproduce your issue. – mm8 Sep 01 '17 at 12:46
  • 1
    It's even reproducing in .NET 4.7. I'll report an issue – Mikolaytis Sep 01 '17 at 12:56
  • This is not bug, just ItemsControl never was designed to work with Virtualising, so it doesn't have full support for it. Use listbox instead, this should fix unstable behavior, so your first solution I'll work. Check this: https://stackoverflow.com/a/45886842/8507673 – sTrenat Sep 01 '17 at 19:23
  • Please, see gist https://gist.github.com/Mikolaytis/82e739aa6adaea328d5369bf3132f016 (it's with `ListBox`), bug is about `ScrollUnit="Pixel"`, not `ItemsControl`. Also, `ItemsControl` works fine with virtualization https://stackoverflow.com/questions/2783845/virtualizing-an-itemscontrol/13392306#13392306 – Mikolaytis Sep 01 '17 at 20:19

1 Answers1

0

I found a surprising solution: use of Virtualizing TreeView with HierarchicalDataTemplate.

<TreeView ItemsSource="{Binding VideosViewModel}"
          ScrollViewer.VerticalScrollBarVisibility="Visible"
          VirtualizingStackPanel.IsVirtualizing="True"
          VirtualizingStackPanel.IsVirtualizingWhenGrouping="True"
          VirtualizingStackPanel.ScrollUnit="Pixel"
          VirtualizingStackPanel.VirtualizationMode="Recycling">
    <TreeView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </TreeView.ItemsPanel>
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="True" />
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Videos}">

            <!--Header-->
            <StackPanel Orientation="Horizontal" Height="500">
                <!--Complex UI-->
            </StackPanel>

            <!--Items-->
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name, Mode=OneTime}" />
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>

        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

This solution is stable and fast.

Mikolaytis
  • 921
  • 1
  • 12
  • 27