0

My MVVM WPF application uses Linq2SQL for using SQL Server Express. I noticed after populating the database with real data I get some big delays for the UI to update and thought is was my query/ grouping strategy. But, while some of the data fills take more than 100ms, rarely do they take more than 200ms but I'm seeing a lag of up to 3 seconds on the window refresh. EDIT FOR BREVITY:

I was wrapping my ItemsControl in a ScrollViewer:

    <ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" ScrollChanged="ScrollViewer_ScrollChanged">
        <ItemsControl x:Name="DivisionItems" ItemsSource="{Binding oObsByDiv}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <uc:ucObservationsHeader/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>

But after some hints from below and reading up on Virtualization I now use a ListBox like so:

<ListBox x:Name="DivisionItems" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" 
ItemsSource="{Binding oObsByDiv}" 
ScrollViewer.CanContentScroll="True"
VirtualizingStackPanel.ScrollUnit="Pixel">
<ListBox.Template>
    <ControlTemplate>
        <ScrollViewer VirtualizingStackPanel.IsVirtualizing="True"
                        VirtualizingStackPanel.VirtualizationMode="Recycling">
            <ItemsPresenter/>
        </ScrollViewer>
    </ControlTemplate>
</ListBox.Template>
<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <VirtualizingStackPanel/>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
    <DataTemplate>
        <uc:ucObservationsHeader/>
    </DataTemplate>
</ListBox.ItemTemplate>

The user control used for the Items in that template then calls another user control that I'm wrapping in another ListBox in a very similar manner:

<ListBox ItemsSource="{Binding lObs}" Grid.Row="1" Grid.Column="1"
HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.CanContentScroll="True"
VirtualizingStackPanel.ScrollUnit="Pixel">
<ListBox.Template>
    <ControlTemplate>
        <ScrollViewer VirtualizingStackPanel.IsVirtualizing="True"
                        VirtualizingStackPanel.VirtualizationMode="Recycling">
            <ItemsPresenter/>
        </ScrollViewer>
    </ControlTemplate>
</ListBox.Template>
<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <VirtualizingStackPanel/>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
        <DataTemplate>
            <uc:ucObservationsView/>
        </DataTemplate>
</ListBox.ItemTemplate>

But the multiple second lag still exists. The outer user control is instantiated 15 times, and the inner one has on average 15 items each. What is it that is breaking virtualization in this case? I keep stripping out the ScrollUnit and CanContentScroll in one or both places, as well as the HorizontalContentAlignement and the HorizontalScrollBar visibility, but those just affect the look without seeming to be the cause for breaking virtualization.

Paul Gibson
  • 622
  • 1
  • 9
  • 23
  • 1
    https://stackoverflow.com/q/2783845/1136211 – Clemens Feb 08 '19 at 22:15
  • @Clemens Thanks for the link, I'm not really sure how to apply it to my situation as I have my Itemscontrol already inside a scroll viewer. I'll play around with it though. Off the top of your head, is it best then to add the scroll viewer per the link inside the ItemsControl template? – Paul Gibson Feb 08 '19 at 22:40
  • @Clemens I modified my main so that I use an ItemsControl only per the link, setting the ScrollViewer.CanContentScroll to true and turning on Virtualization with `VirtualizingPanel.IsVirtualizing=True` but this does not work. Also, it breaks my code as I'm handling the scrollViewer event changed so that the top category visible is reflected in the selected item of a combobox in the main view. Im not sure that this will work anyway, so is there a way to virtualize with a scroll viewer wrapping an items source? – Paul Gibson Feb 08 '19 at 22:58
  • The largest performance hit assuming all view model data routines are Asynchronous is the rendering phase where all context is being inflated. The question then becomes how many things are being displayed? – JWP Feb 09 '19 at 00:55
  • 1
    You need a listbox or listview instead of that itemscontrol if you want to virtualise it's rows. Remove that outer scrollviewer. – Andy Feb 09 '19 at 10:09
  • @ Andy, updated to listbox after researching similar issues when using it, and still virtualizing is not working. The question now shows the listbox xaml code. – Paul Gibson Feb 12 '19 at 16:49

0 Answers0