dub stylee
dub stylee

Reputation: 3342

ListView not updating on CollectionChanged

I am starting to play with Realm, and I am trying to bind a collection from the Realm database to a ListView. The binding works fine, but my ListView does not update when adding new items. My understanding is that IRealmCollection<> implements INotifyCollectionChanged and INotifyPropertyChanged events.

Here is a simple application to reproduce the issue:

View:

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

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <Button Click="ButtonBase_OnClick" Content="Add" />
            <ListView x:Name="ListView">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Id}" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackPanel>
    </Grid>
</Page>

CodeBehind:

namespace App3
{
    public class Thing : RealmObject
    {
        public string Id { get; set; } = Guid.NewGuid().ToString();
    }

    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Realm _realm;
        private IRealmCollection<Thing> things;

        public MainPage()
        {
            this.InitializeComponent();

            _realm = Realm.GetInstance();
            things = (IRealmCollection<Thing>)_realm.All<Thing>();

            ListView.ItemsSource = things;
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            _realm.Write(() =>
            {
                var thing = new Thing();
                _realm.Add(thing);
            });
        }
    }
}

I normally use MVVM (Template10), but this is a simple application to demonstrate the issue. Clicking the Add button adds an item to the database, but the ListView only updates when the application is first loaded. I have read similar questions, but I have not been able to find an answer that works yet. Inverse Relationships and UI-Update not working? is the closest I have found yet, but still does not fix the issue.

EDIT

I can force it to rebind like so:

ListView.ItemsSource = null;
ListView.ItemsSource = things;

But that is not optimal. I am trying to take advantage of Realm's "live objects" where the collection should always know when items are changed or added.

EDIT 2

Setting BindingMode=OneWay in code-behind also does not change the behavior:

_realm = Realm.GetInstance();
things = (IRealmCollection<Thing>)_realm.All<Thing>();

var binding = new Binding
{
    Source = things,
    Mode = BindingMode.OneWay
};

ListView.SetBinding(ListView.ItemsSourceProperty, binding);

SOLUTION

It turned out to be a known issue in IRealmCollection: https://github.com/realm/realm-dotnet/issues/1461#issuecomment-312489046 which is fixed in Realm 1.6.0. I have updated to the pre-release NuGet package and can confirm that the ListView now updates as expected.

Upvotes: 0

Views: 1206

Answers (1)

Vijay Nirmal
Vijay Nirmal

Reputation: 5837

Set Mode=OneWay in Binding

Method 1: In Xaml

<ListView ItemsSource="{x:Bind things, Mode=OneWay}" />

Method 2: In Code Behind

Binding myBind = new Binding();
myBind.Source = things;
myBind.Mode = BindingMode.OneWay;
myListView.SetBinding(ListView.ItemsSourceProperty, myBind);

It is a bug in IRealmCollection. You can use Prerelease Nuget to solve it.

For more info:
IRealmCollection does not update UWP ListView
GitHub Issue: IRealmCollection does not update UWP ListView

Upvotes: 1

Related Questions