Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET MAUI Android ListView issues #16137

Open
GitOguz opened this issue Jul 13, 2023 · 16 comments
Open

.NET MAUI Android ListView issues #16137

GitOguz opened this issue Jul 13, 2023 · 16 comments
Labels
area-controls-listview ListView and TableView platform/android 🤖 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Milestone

Comments

@GitOguz
Copy link

GitOguz commented Jul 13, 2023

Description

I have an ObservableCollection bound to ListView item source. When I remove certain object from the collection I'm getting invisible items in ListView. Also when I scroll through listview items there will be gaps occurring in the list. Items would be invisible.

I have a screeenrecording Screen recording

The Listview lives in a stacklayout with an datatemplate.

I'm using VS Version 17.7.0 Preview 2.0

Each compilation time I will get this message. Am I using an old SDK version? Is there a newer version where this issue maybe is resolved?

C:\Program Files\dotnet\sdk\7.0.400-preview.23274.1\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.RuntimeIdentifierInference.targets(287,5): message NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy

Steps to Reproduce

Create .NET MAUI App for Android
Create mainpage add a listview in stacklayout
Create ObservableCollection
Bind the Artikelen collection to the ListView
Add 30 sample data in to the collection
Remove an items from Artikelen collection observe the listview behaviour.

    public class VoorraadKast {
        public string KastId { get; set; }
        public ObservableCollection<Artikel> Artikelen { get; set; }
    }
public class Artikel : INotifyPropertyChanged {
    private string _ArtikelId;
    public string ArtikelId {
        get { return _ArtikelId; }
        set { 
            _ArtikelId = value;
            NotifyPropertyChanged("ArtikelId");
        }
    }

    private int _Aantal;
    public int Aantal {
        get { return _Aantal; }
        set {
            _Aantal = value;
            NotifyPropertyChanged("Aantal");
        }
    }
    private string _ArtikelName;
    public string ArtikelName 
    {
        get { return _ArtikelName;}
        set {
            _ArtikelName = value;
            NotifyPropertyChanged("ArtikelName");
        }
    }
    public string KastId { get; set; }
    public string Seperator { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string name) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

Link to public reproduction project repository

dont have

Version with bug

7.0.86

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 13

Did you find any workaround?

No

Relevant log output

No response

@GitOguz GitOguz added the t/bug Something isn't working label Jul 13, 2023
@drasticactions drasticactions added the s/needs-repro Attach a solution or code which reproduces the issue label Jul 13, 2023
@ghost
Copy link

ghost commented Jul 13, 2023

Hi @GitOguz. We have added the "s/needs-repro" label to this issue, which indicates that we require steps and sample code to reproduce the issue before we can take further action. Please try to create a minimal sample project/solution or code samples which reproduce the issue, ideally as a GitHub repo that we can clone. See more details about creating repros here: https://github.com/dotnet/maui/blob/main/.github/repro.md

This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@jsuarezruiz jsuarezruiz added the area-controls-listview ListView and TableView label Jul 13, 2023
@GitOguz
Copy link
Author

GitOguz commented Jul 13, 2023

Link to repo Sample project

@ghost ghost added s/needs-attention Issue has more information and needs another look and removed s/needs-repro Attach a solution or code which reproduces the issue labels Jul 13, 2023
@rachelkang
Copy link
Member

@GitOguz Have you tried using CollectionView? Are you only seeing these issues with ListView?

@rachelkang rachelkang added s/needs-info Issue needs more info from the author platform/android 🤖 and removed s/needs-attention Issue has more information and needs another look labels Jul 13, 2023
@ghost
Copy link

ghost commented Jul 13, 2023

Hi @GitOguz. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@GitOguz
Copy link
Author

GitOguz commented Jul 14, 2023

@GitOguz Have you tried using CollectionView? Are you only seeing these issues with ListView?

I didn't test is with CollectionView in my case. I will test that also. Currently this issue is with ListView.

@ghost ghost added s/needs-attention Issue has more information and needs another look and removed s/needs-info Issue needs more info from the author labels Jul 14, 2023
@JohnHDev
Copy link

@rachelkang It could be that this PR fixes this issue: #13669

But that PR appears to have only gone into .NET 8, is that correct? Can we get it merged back into .NET 7 pls? This bug is very easy to replicate, at least for me on iOS. Display a list view in the iOS simulator with 5-10 rows displayed. Toggle dark mode in the simulator, most will disappear. We can't even think of migrating to .NET MAUI with these issues in the production version of .NET, and shouldn't have to wait for November.

@GitOguz
Copy link
Author

GitOguz commented Jul 14, 2023

Hi @GitOguz. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

I've switched to CollectionView. My god that works like a charm. In my case CollectionView solves my issues but the bug in ListView remains.

@rachelkang
Copy link
Member

@JohnHDev #15036 will be considered for backport.

@GitOguz glad to hear CollectionView works well for you! It's definitely the recommended alternative

@rachelkang rachelkang removed the s/needs-attention Issue has more information and needs another look label Jul 17, 2023
@rachelkang rachelkang added this to the Backlog milestone Jul 17, 2023
@ghost
Copy link

ghost commented Jul 17, 2023

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

@XamlTest XamlTest added s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed labels Aug 7, 2023
@XamlTest
Copy link

XamlTest commented Aug 7, 2023

Verified this on Visual Studio Enterprise 17.7.0 Preview 6.0. Repro on Android 13.0-API33(8.0.100-preview.6.23330.14), not repro on Windows 11 and iOS 16.4 with below Project:
ListViewTest.zip

@FlavioGoncalves-Cayas
Copy link

I still experience this issue on version 8.0.6.
And no, switching to CollectionView is not an option as CollectionView does not have ContextActions.
And no, SwipeView is not a replacement for ContextActions as SwipeView has other issues and is not standard Android-Platform behavior.

@GV1072
Copy link

GV1072 commented Feb 21, 2024

I am also getting same issue and posted issue but still not fixed. Please fix as we are not able to migrate to .NET Maui.

Thanks in Advance

@jonathanantoine
Copy link

Any update :) ?

@rafageist
Copy link

rafageist commented Jul 26, 2024

Hello @GitOguz,

I encountered the same issue with ListView on Android. As a workaround, I modified the removal method to recreate the ObservableCollection after removing an item. Here’s the adjusted code:

public void RemoveArtikel(Artikel artikel) 
{
    var art = voorraadkasten.FirstOrDefault(k => k.KastId == artikel.KastId);

    if (art != null)
    {
        art.Artikelen.Remove(artikel);
        art.Artikelen = new ObservableCollection<Artikel>(art.Artikelen);

        if (art.Artikelen.Count == 0)
        {
            voorraadkasten.Remove(art);
        }
    }

    gescandItems.ItemsSource = art.Artikelen;
}

Additionally, it's important to ensure thread-safe access to the collection:

private readonly object _lock = new object();

// ...

voorraadkasten = new ObservableCollection<VoorraadKast>();

BindingBase.EnableCollectionSynchronization(voorraadkasten, _lock, ObservableCollectionCallback);

// ...

private void ObservableCollectionCallback(IEnumerable collection, object context, Action accessMethod, bool writeAccess)
{
    lock (context)
    {
        accessMethod();
    }
}

Recreating the collection after each modification ensures the ListView updates correctly and using BindingBase.EnableCollectionSynchronization helps to handle concurrent access safely.

Also, when initializing the list with a large number of items, ensure you set the ItemsSource after populating the collection to avoid delays:

for (int i = 0; i < 2000; i++)
{
    voorraadKast.Artikelen.Add(new Artikel { KastId = "ABC12345", Aantal = i, ArtikelId = "1234556789", ArtikelName = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", Seperator = "O" });
}

// Set the ItemsSource after populating the collection
gescandItems.ItemsSource = voorraadKast.Artikelen;

Setting the ItemsSource after the collection is fully populated significantly improves performance.

Regards

@GitOguz
Copy link
Author

GitOguz commented Jul 26, 2024

@rafageist Thank you for your tips. Creating the collection over and over again and binding it to the ItemSource isn't that affecting the performance? If you scroll in a big list and remove an item in the middle of the list and recreate the collection and reattach it, won't the list jump back to the top again? You won't be able to keep track of your current location in the list. The user will have to scroll down back to the last position to continue.

Also Im getting the feelling that some action are random run on the UI thread and some on the back by the system. The thread-safe way is indeed the best way to do it.

@rafageist
Copy link

rafageist commented Jul 26, 2024

Hello @GitOguz

Before providing my tips, I downloaded your project, implemented the suggested changes, and conducted all necessary tests. In response to your questions:

  1. I tested with up to 5000 items, and it was extremely fast in displaying, scrolling, and deleting an item. There was no noticeable difference in performance between deleting an item from a list of 60 and a list of 5000.

  2. When an item is deleted, the scroll position is maintained, and it does not jump back to the top. Therefore, the user does not need to scroll back down to their previous position.

Additionally, to address the concern about random thread, I ran some tests and found that using Dispatcher.Dispatch to set the ItemsSource on the main thread is faster most of the time. Here are the results:

Without Dispatcher.Dispatch: 50-90 ms
With Dispatcher.Dispatch: 15-30 ms:

Dispatcher.Dispatch(() => {
    gescandItems.ItemsSource = art.Artikelen;
});

More exhaustive tests could be done by devoting more time to this. Remember, it is a workaround, not a solution.

Thank you for your comments.
Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-listview ListView and TableView platform/android 🤖 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

10 participants