问题描述
我不知所措.. 我一直无法弄清楚为什么我的可观察集合没有实时更新。我必须关闭应用程序并重新打开它才能看到更新.. 所以希望有人能指出我正确的方向。
Nuget 包 - FirebaseDatabase.net MvvmHelpers Xamarin 社区工具包 Xamarin 表单 Xamarin 必备
所以基本上我有一个 ObservableRangeCollection(来自 MVVMHelpers),它从 firebase 实时数据库获取好友列表。
Friends 类是一个非常简单的模型类 -
public class Friend : ObservableObject
{
public Friend()
{
DateAdded = DateTime.Today;
}
string uid;
public string UID
{
get { return uid; }
set
{
SetProperty(ref uid,value);
}
}
DateTime dateAdded;
public DateTime DateAdded
{
get { return dateAdded; }
set
{
SetProperty(ref dateAdded,value);
}
}
string emailAddress;
public string EmailAddress
{
get { return emailAddress; }
set
{
SetProperty(ref emailAddress,value);
}
}
Xaml 页面 - 我有一个绑定到好友的 CollectionView
<CollectionView HorizontalScrollBarVisibility="Default" ItemsSource="{Binding Friends}">
<CollectionView.ItemsLayout>
<LinearItemsLayout ItemSpacing="10" Orientation="Horizontal" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Margin="0"
Padding="0"
BackgroundColor="Transparent"
BorderColor="Transparent"
HasShadow="False">
<StackLayout Orientation="Vertical">
<Frame Margin="0"
Padding="5"
BorderColor="DarkGray"
CornerRadius="25"
HeightRequest="35"
HorizontalOptions="Center"
WidthRequest="35">
<Image BackgroundColor="Transparent"
HorizontalOptions="Center"
Source="{StaticResource UserIcon}" />
</Frame>
<Frame Margin="0"
Padding="0"
BackgroundColor="Transparent">
<Label HorizontalTextAlignment="Center"
Style="{Binding TextSmallCaption}"
Text="{Binding EmailAddress}"
TextColor="Black"
VerticalTextAlignment="Center" />
</Frame>
</StackLayout>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Pageviewmodel - 派生自 Baseviewmodel - 它正确获取并显示好友列表
private ObservableRangeCollection<Friend> _friends = new ObservableRangeCollection<Friend>();
public ObservableRangeCollection<Friend> Friends
{
get { return _friends; }
set
{
_friends = value;
OnPropertyChanged();
}
}
public MessagingPageviewmodel()
{
Title = "Messages";
services = new DBUserService();
CameraBtn = new MvvmHelpers.Commands.Command(Camera);
AddBtn = new MvvmHelpers.Commands.Command(Add);
AddContactBtn = new MvvmHelpers.Commands.Command(AddContact);
FriendsList();
}
public async void FriendsList()
{
// Retrieve my UID from preferences
string myUID = Preferences.Get("UID",string.Empty);
if (IsBusy)
return;
try
{
// Retrieve Friends List
RetrieveFriendsList(myUID);
}
catch (System.Exception ex)
{
await Application.Current.MainPage.displayAlert("Error",ex.ToString(),"OK");
}
finally
{
IsBusy = false;
}
}
private async void RetrieveFriendsList(string myUID)
{
var response = await services.RetrieveFriendsList(myUID);
Friends.ReplaceRange(response);
}
模态页面 - 这是我在实时数据库的列表中添加新朋友的地方 Xaml - 没什么有趣的 - 只是一个添加新朋友的按钮。 页面视图模型 --
private MvvmHelpers.ObservableRangeCollection<Friend> _friends = new MvvmHelpers.ObservableRangeCollection<Friend>();
public MvvmHelpers.ObservableRangeCollection<Friend> Friends
{
get { return _friends; }
set
{
_friends = value;
OnPropertyChanged();
}
}
public AddFriendPageviewmodel()
{
services = new DBUserService();
AddFriendBtn = new MvvmHelpers.Commands.Command(AddFriend);
}
private void AddFriend(object obj)
{
Debug.WriteLine("Selected users to add " + obj);
AddFriendToList(obj.ToString());
}
private async void AddFriendToList(string uid)
{
// Retrieve my UID from preferences
string myUID = Preferences.Get("UID",string.Empty);
// Retrieve friend INFO
var dbUserService = new DBUserService();
var response = await dbUserService.RetrieveUser(uid);
bool result = await dbUserService.RegisterFriendList(myUID,uid,response.EmailAddress);
}
因此,一旦我将新用户添加到实时数据库中,我就会关闭页面 popModalAsync 并且它不会显示更新的列表。如果我关闭应用程序并重新打开它,它会显示更新的列表。所以我在某处缺少通知属性更改。?从我了解到的 MVVMHelpers 大部分情况下都是自己完成的,一旦成员数量发生变化,CollectionView 应该立即触发属性更改。所以我被困住了。不知道我错过了什么。 我保留了不相关的代码(至少我认为是不相关的)如果你需要看到更多让我知道......我会更新帖子。 我的编码水平不是初学者......它更像是中等所以如果你对我来说都是专家,它会超过我的头脑:-)
解决方法
所以对于任何有同样问题的人。我通过试验发现了一个错误,所以不确定哪个更改修复了它,但它就在这里。
我将 ObservableRangeCollection 改回普通的 ObservableCollection
private ObservableCollection<Friend> _friends = new ObservableCollection<Friend>();
public ObservableCollection<Friend> Friends
{
get { return _friends; }
set
{
_friends = value;
OnPropertyChanged();
}
}
在检索方法上我将其更改为
private void RetrieveFriendsList(string myUID)
{
//var response = await services.RetrieveFriendsList(myUID);
//Friends.ReplaceRange(response);
Friends = services.RetrieveFriendsList(myUID);
}
在 DBservice 上,我将方法从 task 更改为 observablecollection
//public async Task<List<Friend>> RetrieveFriendsList (string myUID)
//{
// return (await client
// .Child("Users")
// .Child(myUID)
// .Child("FriendList")
// .OnceAsync<Friend>())
// .Select(u => new Friend
// {
// DateAdded = u.Object.DateAdded,// EmailAddress = u.Object.EmailAddress,// UID = u.Object.UID
// }).ToList();
//}
public ObservableCollection<Friend> RetrieveFriendsList(string myUID)
{
var friendsList = client
.Child("Users")
.Child(myUID)
.Child("FriendList")
.AsObservable<Friend>()
.AsObservableCollection();
return friendsList;
}