dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.26k stars 1.76k forks source link

[iOS] ListView with ViewModel+ObservableCollection won't update ViewCell #25824

Open buurned opened 1 week ago

buurned commented 1 week ago

Description

Hello,

I noticed that if you have a ViewModel that has for example a List or an ObservableCollection (that implement INotifyPropertyChanged) on iOS the size of the row is not dynamically changed when individual elements in the DataTemplate are shown/hidden. On Android everything works as it should.

Demonstration video:

Red = without workaround, green = with workaround

https://github.com/user-attachments/assets/a261503d-0981-4bbf-b64d-55cb2862cf78

Other or similar Tickets

I have seen there are some other errors already related to a ListView and the dynamic display of data / updating of rows - however I could not find an explicit ticket related to an ObservableCollection within a ViewModel => actually the problem should not exist if ObservableCollection would work properly. https://github.com/dotnet/maui/issues/8636 - CollectionView size not updating https://github.com/dotnet/maui/issues/15053 - [iOS] ListView with HasUnevenRows="true" doesn't resize dynamically https://github.com/dotnet/maui/issues/24674 - When using a ListView with bound data, sometimes fields do not wordwrap correctly To find plenty more: [Github Search MAUI platforms/iOS](https://github.com/dotnet/maui/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22platform%2FiOS%20%F0%9F%8D%8E%22%20ListView%20size)

I am using the newest VS 2022 with Workload Maui on latest version.

Steps to Reproduce

  1. Create a ViewModel, add an ObservableCollection
  2. Create ListView, Add Items to ViewModel => ObservableCollection and set the ItemsSource.
  3. Add ItemTapped and try show/hiding e.g. an image.
  4. Row size will not be updated on iOS

Link to public reproduction project repository

https://github.com/buurned/listviewrowsizebug

Version with bug

9.0.0-rc.2.24503.2

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 18.0

Did you find any workaround?

Workaround to solve the current problem

If a custom ObservableCollection is created that triggers OnCollectionChanged(), it works. I have also added the corresponding CustomObservableCollection to the repository. Maybe helps this workaround to give a hint for solving the underlying problem!

 public class CustomObservableCollection<T> : ObservableCollection<T>
 {
     public void UpdateRow(T newItem)
     {
         try
         {
             if (newItem == null)
                 throw new ArgumentNullException(nameof(newItem));

             int index = this.Items.IndexOf(newItem);

             T originalItem = this.Items[index];

             this.Items[index] = newItem;

             OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
             OnPropertyChanged(new PropertyChangedEventArgs("Count"));
             OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItem, originalItem, index));
         }
         catch (Exception ex)
         {
             Debug.WriteLine(ex);
         }
     }
 }

Relevant log output

Ying-6 commented 6 days ago

This issue has been verified using Visual Studio 17.13.0 Preview 1.0 (9.0.10 & 9.0.0-rc.2.24503.2 & 8.0.100). Can repro this issue on iOS platform.