question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ListView bound to ISupportIncrementalLoading collection causes application crash.

See original GitHub issue

Describe the bug

I’m getting a crash to desktop and the following error message when binding ListView or GridView to an item source that implements ISupportIncrementalLoading.

Exception thrown: 'System.ArgumentNullException' in System.Linq.Expressions.dll
Exception thrown at 0x76FAFD62 (KernelBase.dll) in WinUi3Blank.exe: WinRT originate error - 0x80004003 : 'Value cannot be null. (Parameter 'constructor')'.

I have reproduced this issue in a minimal project using the VS2022 built in WinUI 3 project template. The behaviour is the same when targeting x86 and x64 and when targeting Windows 10 19044 and 18363 builds.

I have also tried with all Nuget packages updated to the latest versions, I get the same behaviour.

It seems like a viable workaround is to switch from incremental loading to random loading, the IItemsRangeInfo seems to work fine.

Steps to reproduce the bug

  1. Create a new VS2022 project using the Blank App, Packaged (WinUI 3 in Desktop) template
  2. Create a new class that implements ISupportIncrementalLoading based on the example from the documentation
  3. Create a read only property on MainWindow and initialise it with an instance of your ISupportIncrementalLoading class.
  4. Add a ListView to the main windows xaml and bind ItemsSource to the property.
  5. Run the app

MainWindow.xaml

<Window
    x:Class="WinUi3Blank.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinUi3Blank"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
        <ListView ItemsSource="{x:Bind Items}"></ListView>
    </StackPanel>
</Window>

MainWindow.xaml.cs

namespace WinUi3Blank
{
    /// <summary>
    /// An empty window that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }

        public ISupportIncrementalLoading Items { get; } = new IncrementalLoading();

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            myButton.Content = "Clicked";
        }
    }
}

IncrementalLoading.cs

using Microsoft.UI.Xaml.Data;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;

namespace WinUi3Blank
{
    internal class IncrementalLoading : INotifyCollectionChanged, ISupportIncrementalLoading
    {
        private bool busy;
        private List<int> innerCollection = new List<int>();
        private List<int> itemSource = Enumerable.Range(1, 100).ToList();

        public event NotifyCollectionChangedEventHandler CollectionChanged;

        public bool HasMoreItems { get; private set; } = true;

        public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {
            if (this.busy)
            {
                throw new InvalidOperationException("Only one operation in flight at a time");
            }

            busy = true;

            return AsyncInfo.Run((c) => LoadMoreItemsAsync(c, count));
        }

        private async Task<LoadMoreItemsResult> LoadMoreItemsAsync(CancellationToken c, uint count)
        {
            try
            {
                await Task.Delay(1000);
                var items = itemSource.Take(Convert.ToInt32(count)).ToList();
                itemSource.RemoveRange(0, Convert.ToInt32(count));

                var baseIndex = innerCollection.Count;

                innerCollection.AddRange(items);

                // Now notify of the new items
                NotifyOfInsertedItems(baseIndex, items.Count);

                return new LoadMoreItemsResult { Count = (uint)items.Count };
            }
            finally
            {
                busy = false;
            }
        }

        private void NotifyOfInsertedItems(int baseIndex, int count)
        {
            if (CollectionChanged == null)
            {
                return;
            }

            for (int i = 0; i < count; i++)
            {
                var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, innerCollection[i + baseIndex], i + baseIndex);
                CollectionChanged(this, args);
            }
        }
    }
}

Expected behavior

The app should show the items in the item source but I get a crash to desktop.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.0

Windows app type

  • UWP
  • Win32

Device form factor

Desktop

Windows version

Windows 10 (21H2): Build 19044, Windows 10 (1909): Build 18363

Additional context

No response

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:13 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
manodasanWcommented, Apr 13, 2022

The above workaround is no longer needed. This issue should be fixed in the .NET SDK servicing updates (6.0.202, 6.0.104, 5.0.407, 5.0.213) that came out yesterday.

1reaction
manodasanWcommented, Apr 6, 2022

Per my response in https://github.com/microsoft/CsWinRT/issues/1165, this regression has been fixed in the .24 version of the Windows SDK projection. It is included in the upcoming .NET SDK servicing update. But in the meantime, you can set the below property in your application’s csproj to pick up the .24 version of the Windows SDK projection and unblock yourself. Once the .NET SDK update comes out and you move to it, you should remove the property as it fixes it to that version.

Let me know if it resolves your issue.

<WindowsSdkPackageVersion>10.0.<Target_Windows_Sdk_Version>.24</WindowsSdkPackageVersion>

i.e. if you are targeting 19041, you can set the following the following property:

<WindowsSdkPackageVersion>10.0.19041.24</WindowsSdkPackageVersion>

Read more comments on GitHub >

github_iconTop Results From Across the Web

Setting ListView to visible causes app to crash
Upon setting the 'hidden' listview's IsVisible property to true, I suppose the app tries to fetch its itemssource binding data, upon which the...
Read more >
windows 8 - Clearing ISupportIncrementalLoading
This clears all items from screen so I know it is bound properly. 2) Replace the underlying collection instance entirely that implements ...
Read more >
Infinite Scrolling in Windows Store Apps Using ...
Anyway, in this article, we'll create an example app to see how we can use ISupportIncrementalLoading interface to load items incrementally ...
Read more >
Incremental Loading (Pagination) with MVVM and MVUX
In this post we're going to look at how we can implement paginated, also referred to as incremental, loading for retrieving search results....
Read more >
Implementing the ISupportIncrementalLoading interface in a ...
The ISupportIncrementalLoading interface allows to easily create a collection in which data is loaded incrementally, when a user is about to ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found