наблюдаемая коллекция не обновляется
Я заблудился ... Я не мог понять, почему моя наблюдаемая коллекция не обновляется в реальном времени. Мне нужно закрыть приложение и снова открыть его, чтобы увидеть обновление. Надеюсь, кто-нибудь сможет указать мне правильное направление.
Пакеты Nuget -FirebaseDatabase.netMvvmHelpers инструментарий сообщества Xamarin Формы Xamarin Essentials Xamarin
Итак, в основном у меня есть ObservableRangeCollection (от MVVMHelpers), который получает список друзей из базы данных Firebase Realtime.
Класс друзей - это довольно простой модельный класс -
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 - ничего интересного - просто кнопка для добавления нового друга. PageViewModel -
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 должен инициировать изменение свойства, как только изменится количество членов. Так что я застрял. не уверен, что мне не хватает. Я сохранил нерелевантный код (по крайней мере, то, что я считал нерелевантным), если вам нужно увидеть больше, дайте мне знать ... я обновлю сообщение. Мой уровень кодирования не новичок ... это больше похоже на средний, поэтому, если вы станете экспертом по мне, это будет выше моей головы :-)
1 ответ
так что для тех, у кого такая же проблема. Я обнаружил пробную ошибку, поэтому не уверен, какое изменение исправило ее, но вот оно.
я изменил 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 я изменил метод с задачи на наблюдаемую коллекцию
//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;
}