【问题标题】:Trying to Bind data from realtime database for a list view尝试从实时数据库绑定数据以获取列表视图
【发布时间】:2021-08-23 08:30:25
【问题描述】:

我在 firebase 实时数据库上有一个这样的数据库:

->宠物档案

->Node
     ->UserEmail
     ->PetName
     ->Breed
->Node
     ->UserEmail
     ->PetName
     ->Breed
 ->Node
     ->UserEmail
     ->PetName
     ->Breed

我想绑定这些数据来创建一个列表视图,但是我只想使用具有相同 UserEmail 的分支(只需在列表视图中向他们显示登录用户的宠物)。然而,屏幕上没有出现任何数据。我认为我的 ObservableCollection 填充错误。能不能给我指点一下。

视图模型:

class MyIDPageViewModel : INotifyPropertyChanged
{
    FirebaseHelper firebaseHelper = new FirebaseHelper();

    readonly IList<PetProfile> source;

    public ObservableCollection<PetProfile> PetInfo { get; private set; }
    public IList<PetProfile> EmptyPetInfo { get; private set; }

    public MyIDPageViewModel()
    {
        source = new List<PetProfile>();
        CreatePetProfileCollection();
        OnPropertyChanged();
    }


    private async void CreatePetProfileCollection()
    {
        var petProfiles = await firebaseHelper.GetAllUserPetInfos();
        if(petProfiles != null)
        {
            foreach (var groupitems in petProfiles)
            {
                source.Add(new PetProfile() { PetName = groupitems.PetName });
            }

        }
        
        PetInfo = new ObservableCollection<PetProfile>(source);
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

}

''' Firebase 助手:

public async Task<List<PetProfile>> GetAllUserPetInfos()
    {
        var useremail = Preferences.Get("UserSignInEmail", "");

        var PetProfiles = await GetAllPetInfos();
        await firebase
          .Child("PetProfiles")
          .OnceAsync<PetProfile>();
        return PetProfiles.Where(a => a.UserEmail == useremail).ToList();
       
    }

【问题讨论】:

    标签: c# listview xamarin firebase-realtime-database data-binding


    【解决方案1】:

    有两种方法可以解决此问题,其中一种方法无法正常工作;) 那么为什么它不起作用呢? 即使您正在实现INotifyPropertyChanged 接口,您也从未真正调用过该事件。必须手动调用添加到 PropertyChanged 事件的 PropertyChangedEventHandler 委托。 做的时候 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 您正在这样做,但是您没有在代码中的任何位置调用 OnPropertyChanged

    那么你如何解决这个问题。
    1.

        public IList<PetProfile> EmptyPetInfo { 
            get => source;
            private set {
                if (value != source) {
                    source = value;
                    OnPropertyChanged(nameof(EmptyPetInfo));
                }
            }
        }
    

    在 ObservableCollection 的设置器中调用 OnPropertyChanged

    2.

        private async void CreatePetProfileCollection()
        {
            var petProfiles = await firebaseHelper.GetAllUserPetInfos();
            if(petProfiles != null)
            {
                PetInfo = new ObservableCollection<PetProfile>();
                foreach (var groupitems in petProfiles)
                {
                    PetInfo.Add(new PetProfile() { PetName = groupitems.PetName });
                }
            }
        }
    

    改为将对象添加到 ObservableCollection。

    编辑:没有看到您在没有来自构造函数的参数的情况下调用OnPropertyChanged。您必须提供您希望在视图中更新其值的属性的名称。 在调用OnPropertyChanged 之前,您认为您也在执行异步方法。当你调用一个异步方法时,它会在一个新线程上启动,并且在你的构造函数中继续执行。因此,OnPropertyChanged 将在您收到实时数据之前被调用。

    【讨论】:

    • 嗨,它可以工作,但是我遇到了一个问题。如果我在 addPetPage 上的数据库中添加一个新宠物并返回到带有 collectionView 的页面,它不会更新集合视图,除非我注销用户然后重新登录。为什么会这样?
    • @user2773611 对于仅在数据库内部进行的更改以显示在您的集合中,您必须再次查询数据库。一个简单的想法是为此在您的 collectionView 上添加一个 Button。然后,此按钮将绑定到 ViewModel 中的命令,该命令请求数据库并添加集合中尚不存在的宠物。可能有一些非常聪明的解决方案可以解决您的问题,但遗憾的是我不知道。祝你好运:)
    猜你喜欢
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 2018-10-23
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多