-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
What happened?
Hi, I've noticed a bug where RealmCollection doesn't behave in the same way as ObservableCollection.
From what I've observed, RealmCollection doesn't fire Replace & Reset from INotifyCollectionChanged Interface, thus my app is not updating the UI correctly when I switched from ObservableCollection to RealmDb in my ViewModels. I've made a very simple example to prove my point.
Repro steps
Launch provided code snippet in console application.
Version
net5.0 for console app & Xamarin for my main project issue
What SDK flavour are you using?
Local Database only
What type of application is this?
Xamarin
Client OS and version
Android, iOS, ConsoleApp in .net core Console app for macOS
Code snippets
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.IO; using System.Threading.Tasks; using Nito.AsyncEx; using Realms; namespace ConsoleApp3 { public class Program { public static async Task Main(string[] args) { ObservableCollectionTest(); AsyncContext.Run(RealmCollectionTest); } private static void ObservableCollectionTest() { var item0 = new RealmItem { Id = 0 }; var item1 = new RealmItem { Id = 1 }; var item2 = new RealmItem { Id = 2 }; // add items to collection var colllection = new MyCollection(new[] { item0, item1 }); // listen for notification var actions = new List<NotifyCollectionChangedAction>(5); colllection.CollectionChanged += (sender, eventArgs) => { actions.Add(eventArgs.Action); }; colllection.Add(item2); // Add items colllection.MoveItem(1, 2); // Move items colllection.Remove(item0); // Remove items colllection[1] = item2; // Replace items colllection.Clear(); // Reset items Console.WriteLine($"Actions for ObservableCollection: {string.Join(", ", actions)}"); } private static void RealmCollectionTest() { var path = Path.Combine(Environment.CurrentDirectory, "realm.realm"); var realm = Realm.GetInstance(new RealmConfiguration(path)); var item0 = new RealmItem { Id = 0 }; var item1 = new RealmItem { Id = 1 }; var item2 = new RealmItem { Id = 2 }; var colllection = new RealmWithCollection { Id = "col" }; // add items to persistent cache & to collection realm.Write(() => { realm.RemoveAll(); realm.Add(item0); realm.Add(item1); realm.Add(item2); realm.Add(colllection); colllection.Items.Add(item0); colllection.Items.Add(item1); }); // listen for notification var actions = new List<NotifyCollectionChangedAction>(5); colllection.Items.AsRealmCollection().CollectionChanged += (sender, eventArgs) => { actions.Add(eventArgs.Action); }; realm.Write(() => colllection.Items.Add(item2)); // Add items realm.Write(() => colllection.Items.Move(item1, 2)); // Move items realm.Write(() => colllection.Items.Remove(item0)); // Remove items realm.Write(() => colllection.Items[1] = item2); // Replace items realm.Write(() => colllection.Items.Clear()); // Reset items Console.WriteLine($"Actions for RealmCollection: {string.Join(", ", actions)}"); } class MyCollection : ObservableCollection<RealmItem> { public MyCollection(IEnumerable<RealmItem> collection) : base(collection) { } public new void MoveItem(int oldIndex, int newIndex) { base.MoveItem(oldIndex, newIndex); } } public class RealmWithCollection : RealmObject { [PrimaryKey] public string Id { get; set; } public IList<RealmItem> Items { get; } } public class RealmItem : RealmObject { [PrimaryKey] public int Id { get; set; } } } }
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net5.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="BenchmarkDotNet" Version="0.13.1" /> <PackageReference Include="Fody" Version="6.6.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Nito.AsyncEx.Context" Version="5.1.2" /> <PackageReference Include="Realm" Version="10.9.0" /> <PackageReference Include="Realm.Fody" Version="10.9.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> </Project>
Relevant log output
Actions for ObservableCollection: Add, Move, Remove, Replace, Reset Actions for RealmCollection: Add, Move, Remove
^ ObservableCollection & RealmCollection should fire INotifyCollectionChanged events in the same way
- depends on
-
RCORE-1010 Add support for replaced indexes in CollectionChangeSet
- Closed