CollectionView doesn't update until I stop and reload app

MrZeeIndo 161 Reputation points
2021-06-09T06:37:59.727+00:00

Hi I am Building a Xamarin App using a firebase realtime db that looks like this:

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

I have managed to make a collection view showing all the pets of the user by using the useremail as a key. However I am having a problem. If I add a new pet in the database on the addPetPage and navigate back to the page with the collectionView it doesn't update the collectionView unless I reload the App. Why would that be?

here is my code for the the ViewModel:

class MyIDPageViewModel : INotifyPropertyChanged
    {
        FirebaseHelper firebaseHelper = new FirebaseHelper();
        public Command AddAPetCommand { get; set; }

        private string _petName;
        private string _breed;
        private string _dob;
        private string _gender;
        private string _weight;
        private string _petCareInfo;

        public string PetName { get => _petName;set {_petName = value; }}
        public string Breed { get => _breed;set { _breed = value;}}
        public string DOB {get => _dob; set { _dob = value;}}
        public string Gender{get => _gender; set{ _gender = value;}}
        public string Weight{get => _weight; set{_weight = value;}}
        public string PetCareInfo {get => _petCareInfo; set{ _petCareInfo = value; }}


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

        public MyIDPageViewModel()
        {
            source = new ObservableCollection<PetProfile>();
            AddAPetCommand = new Command( () => PerformAddAPetCommand());
            CreatePetProfileCollection();
        }

        private async void PerformAddAPetCommand()
        {
            await firebaseHelper.AddPetInfo(_petName, _breed, _dob, _weight, _gender, _petCareInfo);

            var petProfiles = await firebaseHelper.GetAllUserPetInfos();
            if (petProfiles != null)
            {
                EmptyPetInfo = new ObservableCollection<PetProfile>();
                foreach (var groupitems in petProfiles)
                {
                    EmptyPetInfo.Add(new PetProfile() { PetName = groupitems.PetName, UserEmail = groupitems.UserEmail, Breed = groupitems.Breed, DOB = groupitems.DOB, Gender = groupitems.Gender, Weight = groupitems.Weight, CareInformation = groupitems.CareInformation });
                }
                OnPropertyChanged();
            }
        }

        public async void CreatePetProfileCollection()
        {
            var petProfiles = await firebaseHelper.GetAllUserPetInfos();
            if (petProfiles != null)
            {
                EmptyPetInfo = new ObservableCollection<PetProfile>();
                foreach (var groupitems in petProfiles)
                {
                    EmptyPetInfo.Add(new PetProfile() { PetName = groupitems.PetName, UserEmail = groupitems.UserEmail, Breed = groupitems.Breed, DOB = groupitems.DOB, Gender = groupitems.Gender, Weight = groupitems.Weight, CareInformation = groupitems.CareInformation });
                }
            }
        }

       #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

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

Here is the xaml page:

<ContentPage.Content>
        <ScrollView>
        <StackLayout>
            <Label Text="Add a Pet:"
                VerticalOptions="Start" 
                HorizontalOptions="Start"
                   Padding="15"
                   FontSize="Large"
                   FontAttributes="Bold"/>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="360"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <Image Source="https://i.pinimg.com/564x/bf/99/57/bf9957520ad1e6145cadc9c1c2e08b0f.jpg"
                   Aspect="AspectFit"/>

                <Image Source="https://cdn1.iconfinder.com/data/icons/rounded-black-basic-ui/139/Photo_Add-RoundedBlack-512.png" 
                       Scale="0.25"/>
            </Grid>

            <Grid Margin="15" Padding="0" RowSpacing="0" ColumnSpacing="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="60"/>
                    <RowDefinition Height="60"/>
                    <RowDefinition Height="60"/>
                    <RowDefinition Height="60"/>
                    <RowDefinition Height="60"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <Label Text="Name:" Padding="0" FontAttributes="Bold" FontSize="20" Grid.Row="0" Grid.Column="0" VerticalOptions="End"/>
                    <Label Text="Breed:" Padding="0" FontAttributes="Bold" FontSize="20" Grid.Row="0" Grid.Column="1" VerticalOptions="End"/>
                    <Label Text="Age:" Padding="0" FontAttributes="Bold" FontSize="20" Grid.Row="2" Grid.Column="0" VerticalOptions="End"/>
                    <Label Text="Weight:" Padding="0" FontAttributes="Bold" FontSize="20" Grid.Row="2" Grid.Column="1" VerticalOptions="End"/>
                    <Label Text="Gender:" Padding="0" FontAttributes="Bold" FontSize="20" Grid.Row="4" Grid.Column="0" VerticalOptions="End"/>

                    <Entry x:Name="PetName" Text="{Binding PetName}" Grid.Row="1" Grid.Column="0" Background="white" PlaceholderColor="Black" VerticalOptions="Start"/>
                    <Entry x:Name="Breed" Text="{Binding Breed}" Grid.Row="1" Grid.Column="1" Background="white" PlaceholderColor="Black" VerticalOptions="Start"/>
                    <DatePicker x:Name="DOB" Date="{Binding DOB}" Grid.Row="3" Grid.Column="0" VerticalOptions="Start" Format="dd-MM-yyyy"/>
                    <Picker x:Name="gender" SelectedItem="{Binding Gender}" Title="Select a Gender" TitleColor="Black" Grid.Row="5" Grid.Column="0" VerticalOptions="Start">
                    <Picker.Items>
                        <x:String>Male</x:String>
                        <x:String>Female</x:String>
                    </Picker.Items>
                </Picker>

                    <Picker x:Name="Weight" SelectedItem="{Binding Weight}" Title="Select a Weight" TitleColor="Black" Grid.Row="3" Grid.Column="1" VerticalOptions="Start">
                        <Picker.Items>
                            <x:String>S: 2 - 8 Kg</x:String>
                            <x:String>M: 9 - 20 Kg</x:String>
                            <x:String>L: 21 - 40 Kg</x:String>
                            <x:String>XL: 41+ Kg</x:String>
                        </Picker.Items>
                    </Picker>
                </Grid>

                <Label x:Name="CareInformation" Text="Care Information" FontSize="Large" FontAttributes="Bold" Margin="15"/>
                <Editor x:Name="PetCareInfo" Text="{Binding PetCareInfo}" Placeholder="Help for our dogwalkers and sitters:" Margin="15"/>

                <Button Text="Submit">
                    <Button.Behaviors>
                        <behaviors:EventToCommandBehavior EventName="Clicked" Command="{Binding AddAPetCommand}"/>


                    </Button.Behaviors>
                </Button>


            </StackLayout>
        </ScrollView>
    </ContentPage.Content>

The Page with the collection view:

<ContentPage.BindingContext>
        <local:MyIDPageViewModel/>
    </ContentPage.BindingContext>
    <ContentPage.Content>
        <StackLayout>
            <Label 
                   Text="My Id"
                   VerticalOptions="Start" 
                   HorizontalOptions="Start" 
                   Padding="15"
                   FontSize="Title"
                   FontAttributes="Bold"
                   TextColor="Black"/>
            <Label Text="Name:" FontSize="Subtitle" Margin="15,0" FontAttributes="Bold"/>
            <Label x:Name="UserName" FontSize="Medium" Margin="15,0"/>
            <Label Text="Email Address:" FontSize="Subtitle" Margin="15,0" FontAttributes="Bold"/>
            <Label x:Name="UserEmail" FontSize="Medium" Margin="15,0"/>
            <Label Text="Phone Number:" FontSize="Subtitle" Margin="15,0" FontAttributes="Bold"/>
            <Label x:Name="UserPhoneNumber" FontSize="Medium" Margin="15,0"/>
            <Label Text="Address:" FontSize="Subtitle" Margin="15,0" FontAttributes="Bold"/>
            <Label x:Name="UserAddress" FontSize="Medium" Margin="15,0"/>

            <Label Text="My Pets:" FontSize="Large" Margin="15,0" FontAttributes="Bold"/>
            <CollectionView  ItemsSource="{Binding EmptyPetInfo}" >
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Grid Padding="10">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Label Grid.Column="0"
                                   Grid.Row="0"
                       Text="{Binding PetName}"
                       FontAttributes="Bold" />
                            <Label Grid.Row="0"
                       Grid.Column="2"
                       Text="View Profile"
                       FontAttributes="Italic"
                       VerticalOptions="End" />

                            <Label Grid.Column="1"
                                   Grid.Row="0"
                       Text="{Binding PetName}"
                       FontAttributes="Bold" />
                            <Label  Grid.Row="0"
                                    Grid.Column="2"
                                    Text="View Profile"
                                    FontAttributes="Italic"
                                    VerticalOptions="End">
                                <Label.GestureRecognizers>
                                    <TapGestureRecognizer Tapped="ViewPetProfile_Tapped"/>
                                </Label.GestureRecognizers>
                            </Label>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

            <Label Text="+ Add pet" HorizontalOptions="Center" FontAttributes="Bold">
                <Label.GestureRecognizers>
                    <TapGestureRecognizer Tapped="AddaPet_Tapped"/>
                </Label.GestureRecognizers>
            </Label>
            <Button Text="Edit" HorizontalOptions="End" Margin="15" Clicked="Edit_Clicked"/>

        </StackLayout>
    </ContentPage.Content>
</ContentPage>
Developer technologies | .NET | Xamarin
{count} votes

1 answer

Sort by: Most helpful
  1. Kyle Wang 5,531 Reputation points Microsoft External Staff
    2021-06-09T08:49:45.04+00:00

    Hi MrZeeIndo-6537,

    Welcome to our Microsoft Q&A platform!

    You can define a method to update the "EmptyPetInfo" in "CollectionViewPageViewModel".

    class CollectionViewPageViewModel  
    {  
        public ObservableCollection<PetProfile> EmptyPetInfo { get; set; }  
      
        public void Refresh()  
        {  
            EmptyPetInfo.Clear();  
            var petProfiles = /* call some method to get items from firebase */  
    
            foreach (PetProfile profile in petProfiles)  
            {  
                EmptyPetInfo.Add(c);  
            }  
        }  
    }  
    

    Then override OnAppearing of "CollectionViewPage".

    protected override void OnAppearing()  
    {  
        base.OnAppearing();  
      
        (BindingContext as CollectionViewPageViewModel).Refresh();  
    }  
    

    Regards,
    Kyle


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.