【问题标题】:ListView not updating on CollectionChangedListView 未在 CollectionChanged 上更新
【发布时间】:2017-07-28 17:54:17
【问题描述】:

我开始使用 Realm,我正在尝试将 Realm 数据库中的集合绑定到 ListView。绑定工作正常,但我的ListView 在添加新项目时没有更新。我的理解是IRealmCollection<> 实现了INotifyCollectionChangedINotifyPropertyChanged 事件。

这是一个重现问题的简单应用程序:

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);
            });
        }
    }
}

我通常使用 MVVM (Template10),但这是一个演示问题的简单应用程序。单击Add 按钮将一个项目添加到数据库中,但ListView 仅在首次加载应用程序时更新。我读过类似的问题,但我还没有找到有效的答案。 Inverse Relationships and UI-Update not working? 是我找到的最接近的,但仍然没有解决问题。

编辑

我可以像这样强制它重新绑定:

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

但这不是最优的。我正在尝试利用 Realm 的“活动对象”,其中集合应该始终知道何时更改或添加项目。

编辑 2

在代码隐藏中设置 BindingMode=OneWay 也不会改变行为:

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

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

ListView.SetBinding(ListView.ItemsSourceProperty, binding);

解决方案

事实证明这是IRealmCollection 中的一个已知问题:https://github.com/realm/realm-dotnet/issues/1461#issuecomment-312489046 已在 Realm 1.6.0 中修复。我已更新到预发布的 NuGet 包,并且可以确认 ListView 现在按预期更新。

【问题讨论】:

  • 试试我发的solution。可能适用于您的情况
  • 该项目已添加到数据库中,但您用作 ListView 的 ItemSource 的“事物”集合不知道添加的新项目。所以你需要从数据库中重新查询新项目并将它们加载到'things'集合中。
  • @Nobody 运气不好。 UpdateLayout 方法没有任何区别,看起来 InvalidateVisual 对于 UWP 不存在。

标签: c# xaml uwp realm


【解决方案1】:

Binding中设置Mode=OneWay

方法 1:在 Xaml 中

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

方法 2:在代码后面

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

这是 IRealmCollection 中的一个错误。你可以使用Prerelease Nuget来解决。

欲了解更多信息:
IRealmCollection does not update UWP ListView
GitHub Issue: IRealmCollection does not update UWP ListView

【讨论】:

  • TextBlock 绑定不影响ListView.ItemsSource 绑定。将ListView 的绑定更改为OneWay 也不会改变行为。
  • 使用Mode=OneWay 作为您的ListView。我已经更新了我的答案
  • 到目前为止,我唯一能更新ListView 的方法是将ItemsSource 设置为null 并重新绑定。查看更新的问题。
  • 是的,它没有改变任何东西。似乎 CollectionChanged 没有触发或类似通知ListView 刷新ItemsSource....
  • @dubstylee 为您的INotifyCollectionChanged附上一些示例代码
猜你喜欢
  • 1970-01-01
  • 2014-10-16
  • 1970-01-01
  • 2014-07-09
  • 1970-01-01
  • 2018-07-05
  • 2018-01-20
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多