【问题标题】:Inverse Relationships and UI-Update not working?反向关系和 UI 更新不起作用?
【发布时间】:2017-03-07 11:29:38
【问题描述】:

我目前正在开发一个信使应用程序。因此我使用领域将数据存储在设备上。我的应用程序包含一个页面来表示列表视图中的所有聊天线程。因此,我将 ListView 绑定到了 IRealmCollection。如果我在 Messagethread 中更改属性,我可以看到 Litview 正在相应更新。但是当我在线程中插入一条消息时,用户界面不会。

public class Messagethread : RealmObject
{
    [PrimaryKey]
    public string Guid { get; set; }

    public IList<User.User> Users { get;  }

    [Backlink(nameof(Message.Message.MessageThread))]
    public IQueryable<Message.Message> Messages { get; }

    public User.User Owner { get; set; }

    public string Title { get; set; }

    public int CountOfUnreadMessages { get; set; }
    public bool IsPrivate { get; set; }

    public DateTimeOffset LastSyncDate { get; set; }
    public DateTimeOffset LastSingleSyncDate { get; set; }
    public int ItemSyncStatus { get; set; }

    public void CallPropertyChanged(string name)
    {
        base.OnPropertyChanged(name);
    }
}

public class Message : RealmObject
{
    [PrimaryKey]
    public string Guid { get; set; }

    public Messagethread MessageThread { get; set; }
    public User.User Author { get; set; }

    public string Body { get; set; }

    [Backlink(nameof(MessageAttachement.MessageAttachement.Message))]
    public IQueryable<MessageAttachement.MessageAttachement> Attachements { get; }

    public string Title { get; set; }
    public DateTimeOffset SendDate { get; set; }
    public bool SystemMessage { get; set; }
    public DateTimeOffset LocalSyncDate { get; set; }
    public DateTimeOffset ChangeTime { get; set; }

    public bool IsSynced { get; set; }
}

当我插入新消息时,我尝试在“消息”属性上调用 PropertyChanged。但这也没有用。

如果反向链接属性发生更改,是否有办法实现自动更新 UI 的行为?

感谢您的帮助 朱利安

【问题讨论】:

  • 你是如何在Messagethread中绑定反向链接属性(Messages)的?
  • 嘿@SushiHangover,我使用 绑定 Backlink'd 属性。
  • 我会反向链接 from Message to MessageThread,然后更新所有通知(INotifyPropertyChanged)。如果可以,我会发布一个示例帮助。
  • 嘿,@SushiHangover 如果你能给我发一个小例子就好了:)。

标签: c# xamarin realm


【解决方案1】:

一个快速的 One2Many 示例,没有 MVVM/Viper/MVC/MVP 和 XAML 以使其尽可能简单。

数据模型(你的简化版):

One to Many导航(消息线程-&gt;*消息)

public class MessageThread : RealmObject
{
    [PrimaryKey]
    public string Guid { get; set; }

    public IList<Message> Messages { get; }
}

public class Message : RealmObject
{
    [PrimaryKey]
    public string Guid { get; set; }
    public string Body { get; set; }

    [Backlink(nameof(MessageThread.Guid))]
    public MessageThread Thread { get; }
}

简单的主/详细表单 UI:

Xamarin.Forms应用实例:

public class BackLinkApp : Application
{
    readonly Realm realm;
    readonly IRealmCollection<MessageThread> allMessageThreads;
    readonly Button addMessageThread;
    readonly Button addMessageToThread;
    IRealmCollection<MessageThread> currentMessageThread;
    string currentMessageThreadPriKey;

    public BackLinkApp()
    {
        realm = Realm.GetInstance("backlinks.realm");
        allMessageThreads = (IRealmCollection<MessageThread>)realm.All<MessageThread>();

        var messageCell = new DataTemplate(typeof(TextCell));
        messageCell.SetBinding(TextCell.TextProperty, "Body");
        messageCell.SetBinding(TextCell.DetailProperty, "Guid");
        var messageListView = new ListView
        {
            ItemTemplate = messageCell,
        };
        var threadCell = new DataTemplate(typeof(TextCell));
        threadCell.SetBinding(TextCell.TextProperty, "Guid");
        var messageThreadListView = new ListView
        {
            ItemsSource = allMessageThreads,
            ItemTemplate = threadCell
        };

        messageThreadListView.ItemSelected += (sender, e) =>
        {
            currentMessageThreadPriKey = (messageThreadListView.SelectedItem as MessageThread).Guid;
            currentMessageThread = (IRealmCollection<MessageThread>)realm.All<MessageThread>().Where((messageThread) => messageThread.Guid == currentMessageThreadPriKey);
            messageListView.ItemsSource = currentMessageThread?.FirstOrDefault()?.Messages;
            addMessageToThread.IsEnabled = currentMessageThread?.Count() > 0;
        };

        addMessageThread = new Button { Text = "Add New MessageThread" };
        addMessageThread.Clicked += (sender, e) =>
        {
            realm.Write(() =>
            {
                var messageThread = new MessageThread { Guid = Guid.NewGuid().ToString() };
                realm.Add(messageThread);
            });
        };

        addMessageToThread = new Button { Text = "Add New Message to Thread", IsEnabled = false };
        addMessageToThread.Clicked += (sender, e) =>
        {
            realm.Write(() =>
            {
                currentMessageThread = (IRealmCollection<MessageThread>)realm.All<MessageThread>().Where((messageThread) => messageThread.Guid == currentMessageThreadPriKey);
                var counter = currentMessageThread.FirstOrDefault().Messages.Count() + 1;
                var message = new Message { Guid = Guid.NewGuid().ToString(), Body = $"StackoverFlow:{counter}" };
                currentMessageThread?.FirstOrDefault()?.Messages.Add(message);
            });
        };

        MainPage = new ContentPage
        {
            Content = new StackLayout
            {
                VerticalOptions = LayoutOptions.Center,
                Children = {
                    addMessageThread, messageThreadListView, addMessageToThread, messageListView
                }
            }
        };
    }
}

通过将messageListView.ItemsSource 的绑定源设置为当前 选择的MessageThread 对象的Messages 属性,当新消息添加到该线程时,您的UI 将“自动”更新:

messageListView.ItemsSource = currentMessageThread?.FirstOrDefault()?.Messages;

【讨论】:

  • 我明白了你的例子背后的想法。我会尝试一下。但是我得到“Message.MessageThread 已应用 [Backlink],但不是 IQueryable”编译错误。我想它仍然可以在没有反向链接的情况下工作。我会告诉你的!
  • 它工作正常。非常感谢您的帮助并花时间解决我的问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 2020-12-02
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
相关资源
最近更新 更多