Passing Data from collectionview to details page Shell Navigation

MrZeeIndo 161 Reputation points
2021-06-15T03:01:28.65+00:00

Hi,

I have a collection view with a list of names and a label view profile. When I click view profile I want to navigate to the details page. However I am confused with the shell navigation and how to pass data from one page to another. As well as with collection view. This is my first time working with it. I am clicking on viewprofile and navigating to the details page however the data I pass through doesn't pass. The PetName doesn't appear as I guess there is no value. I am using a command to call navigation.

I guess I am unsure how to get the Petsname when i click view profile then pass it on.

Thanks

MyIDPageViewModel:

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

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

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

            private async void OnNav(PetProfile PetDetailsPage)
            {           

                if (PetDetailsPage == null)
                    return;

                await Shell.Current.GoToAsync($"//MyIDPage/PetDetailsPage?PetName={PetDetailsPage.PetName}");
            }

            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 });
                    }
                }
            }


            public async void Refresh()
            {
                EmptyPetInfo.Clear();
                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

My collection View:

<CollectionView  ItemsSource="{Binding EmptyPetInfo}" SelectedItem="{Binding SelectedPet, Mode=OneWay}" SelectionChanged="OnCollectionViewSelectionChanged">
                    <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="Image Goes Here"
                                       FontAttributes="Bold" />
                                <Label Grid.Column="1"
                                       Grid.Row="0"
                                       Text="{Binding PetName}"
                                       FontAttributes="Bold"
                                       x:Name="labelpetname"/>
                                <Label  Grid.Row="0"
                                        Grid.Column="2"
                                        Text="View Profile"
                                        FontAttributes="Italic"
                                        VerticalOptions="End"                                
                                        >
                                    <Label.GestureRecognizers>
                                        <TapGestureRecognizer Command="{Binding NavToDetailCommand, Source={
                                        RelativeSource AncestorType={x:Type local:MyIDPageViewModel}
                                    }}"
                                    CommandParameter="{Binding .}">
                                        </TapGestureRecognizer>
                                    </Label.GestureRecognizers>
                                </Label>
                            </Grid>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>

PetDetailsPage:

public partial class PetDetailsPage : ContentPage
        {
            FirebaseHelper firebaseHelper = new FirebaseHelper();
            private string _PetName;
            public string PetName
            {
                get => _PetName;
                set
                {
                    if (value != _PetName)
                    {
                        _PetName = value;
                    }
                }
            }

            public PetDetailsPage()
            {
                InitializeComponent();
                RetrivePetInfo();

            }

            private async void RetrivePetInfo()
            {
                var pet = await firebaseHelper.GetPet(_PetName);
                if (pet != null)
                {
                    petname.Text = pet.PetName;
                }

            }

Code for retrieving PetInfo from firebase:

public async Task<PetProfile> GetPet(string petname)
        {
            var useremail = Preferences.Get("UserSignInEmail", "");

            var PetProfiles = await GetAllPetInfos();
            await firebase
              .Child("PetProfiles")
              .OnceAsync<PetProfile>();
            return PetProfiles.Where(a => a.UserEmail == useremail && a.PetName == petname).FirstOrDefault();
        }
Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,334 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,819 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 74,081 Reputation points Microsoft Vendor
    2021-06-16T02:56:44.27+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    Firstly, you can change the Command binding way in the Label.GestureRecognizers of CollectionView.

       <ContentPage.Content>  
               <StackLayout>  
                   <CollectionView x:Name="petCollectionView"  ItemsSource="{Binding EmptyPetInfo}" SelectedItem="{Binding SelectedPet, Mode=OneWay}" SelectionChanged="CollectionView_SelectionChanged">  
                       <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="Image Goes Here"  
                                              FontAttributes="Bold" />  
                                   <Label Grid.Column="1"  
                                              Grid.Row="0"  
                                              Text="{Binding PetName}"  
                                              FontAttributes="Bold"  
                                              x:Name="labelpetname"/>  
                                   <Label  Grid.Row="0"  
                                               Grid.Column="2"  
                                               Text="View Profile"  
                                               FontAttributes="Italic"  
                                               VerticalOptions="End"                                  
                                               >  
                                       <Label.GestureRecognizers>  
                                           <TapGestureRecognizer  Command="{Binding Path=BindingContext.NavToDetailCommand, Source={x:Reference Name=petCollectionView}}"   
                                           CommandParameter="{Binding .}">  
                                           </TapGestureRecognizer>  
                                       </Label.GestureRecognizers>  
                                   </Label>  
                               </Grid>  
                           </DataTemplate>  
                       </CollectionView.ItemTemplate>  
                   </CollectionView>  
               </StackLayout>  
           </ContentPage.Content>  
    

    Then, you can get the current model in the OnNav method of MyIDPageViewModel.cs. I do not have firebase, So I add static data for testing.

    Here is MyIDPageViewModel.cs.

       using System;  
       using System.Collections.Generic;  
       using System.Text;  
       using System.Collections.ObjectModel;  
       using System.ComponentModel;  
       using System.Runtime.CompilerServices;  
       using System.Text;  
       using Xamarin.Forms;  
       using System.Threading.Tasks;  
       using System.Windows.Input;  
       using System.Linq;  
         
       namespace ShellCollectionVPassData.ViewModels  
       {  
           class MyIDPageViewModel : INotifyPropertyChanged  
           {  
               FirebaseHelper firebaseHelper = new FirebaseHelper();  
               public ICommand NavToDetailCommand { get; set; }  
         
               public ObservableCollection<PetProfile> source;  
               public ObservableCollection<PetProfile> PetInfo { get; private set; }  
               public ObservableCollection<PetProfile> EmptyPetInfo  
               {  
                   get => source;  
                   private set  
                   {  
                       if (value != source)  
                       {  
                           source = value;  
                           OnPropertyChanged(nameof(EmptyPetInfo));  
                       }  
                   }  
               }  
         
               public MyIDPageViewModel()  
               {  
                   source = new ObservableCollection<PetProfile>();  
                   CreatePetProfileCollection();  
                   NavToDetailCommand = new Command<PetProfile>(OnNav);  
               }  
         
               private async void OnNav(PetProfile PetDetailsPage)  
               {  
         
                   if (PetDetailsPage == null)  
                       return;  
                    
                   await Shell.Current.GoToAsync($"PetDetailsPage?name={PetDetailsPage.PetName}");  
               }  
         
               public async void CreatePetProfileCollection()  
               {  
                   var petProfiles =  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 });  
                       }  
                   }  
               }  
         
         
               public async void Refresh()  
               {  
                   EmptyPetInfo.Clear();  
                   var petProfiles =  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  
           }  
         
           internal class FirebaseHelper  
           {  
               ObservableCollection<PetProfile> petProfiles;  
               public FirebaseHelper()  
               {  
                   petProfiles = new ObservableCollection<PetProfile>();  
                   petProfiles.Add(new PetProfile() { PetName = "Pet 1", UserEmail = "pet1@test.com", Breed = "Breed1", CareInformation = "info", DOB = "dd", Gender = "male", Weight = "210" });  
                   petProfiles.Add(new PetProfile() { PetName = "Pet 2", UserEmail = "pet1@test.com", Breed = "Breed1", CareInformation = "info", DOB = "dd", Gender = "male", Weight = "210" });  
                   petProfiles.Add(new PetProfile() { PetName = "Pet 3", UserEmail = "pet1@test.com", Breed = "Breed1", CareInformation = "info", DOB = "dd", Gender = "male", Weight = "210" });  
                   petProfiles.Add(new PetProfile() { PetName = "Pet 4", UserEmail = "pet1@test.com", Breed = "Breed1", CareInformation = "info", DOB = "dd", Gender = "male", Weight = "210" });  
                   petProfiles.Add(new PetProfile() { PetName = "Pet 5", UserEmail = "pet1@test.com", Breed = "Breed1", CareInformation = "info", DOB = "dd", Gender = "male", Weight = "210" });  
                   petProfiles.Add(new PetProfile() { PetName = "Pet 6", UserEmail = "pet1@test.com", Breed = "Breed1", CareInformation = "info", DOB = "dd", Gender = "male", Weight = "210" });  
                   petProfiles.Add(new PetProfile() { PetName = "Pet 7", UserEmail = "pet1@test.com", Breed = "Breed1", CareInformation = "info", DOB = "dd", Gender = "male", Weight = "210" });  
               }  
                
               internal ObservableCollection<PetProfile> GetAllUserPetInfos()  
               {  
                   // throw new NotImplementedException();  
         
                  
         
                   return petProfiles;  
               }  
         
               internal PetProfile GetPet(string petName)  
               {  
                   //throw new NotImplementedException();  
         
                return petProfiles.Where(a => a.PetName == petName).FirstOrDefault();  
         
               }  
         
               //public async Task<PetProfile> GetPet(string petname)  
               //{  
               //    var useremail = Preferences.Get("UserSignInEmail", "");  
               //    var PetProfiles = await GetAllPetInfos();  
               //    await firebase  
               //      .Child("PetProfiles")  
               //      .OnceAsync<PetProfile>();  
               //    return PetProfiles.Where(a => a.UserEmail == useremail && a.PetName == petname).FirstOrDefault();  
               //}  
           }  
         
           public class PetProfile  
           {  
               public string PetName { get; set; }  
               public string UserEmail { get; set; }  
               public string Breed { get; set; }  
         
               public string DOB { get; set; }  
         
               // Gender = groupitems.Gender, Weight = groupitems.Weight, CareInformation = groupitems.CareInformation  
         
               public string Gender { get; set; }  
         
               public string Weight { get; set; }  
         
               public string CareInformation { get; set; }  
           }  
       }  
    

    I change your navigate way with await Shell.Current.GoToAsync($"PetDetailsPage?name={PetDetailsPage.PetName}"); in above MyIDPageViewModel.cs. And you need to RegisterRoute for PetPage and PetDetailsPage in the AppShell.xaml.cs code

       public partial class AppShell : Xamarin.Forms.Shell  
           {  
               public AppShell()  
               {  
                   InitializeComponent();  
                   Routing.RegisterRoute(nameof(ItemDetailPage), typeof(ItemDetailPage));  
                   Routing.RegisterRoute(nameof(NewItemPage), typeof(NewItemPage));  
                   Routing.RegisterRoute(nameof(PetPage), typeof(PetPage));  
                   Routing.RegisterRoute(nameof(PetDetailsPage), typeof(PetDetailsPage));  
               }  
         
           }  
    

    In the end, open the PetDetailsPage.xaml.cs, you need to add [QueryProperty(nameof(PetName), "name")] attribute above the PetDetailsPage .cs. Then move RetrivePetInfo method to the OnAppearing method, because when you execute RetrivePetInfo in PetDetailsPage's constructor, PetNamedo not get the value at that time.

       [XamlCompilation(XamlCompilationOptions.Compile)]  
           [QueryProperty(nameof(PetName), "name")]  
           public partial class PetDetailsPage : ContentPage  
           {  
               FirebaseHelper firebaseHelper = new FirebaseHelper();  
               private string _PetName;  
               public string PetName  
               {  
                   get => _PetName;  
                   set  
                   {  
                       if (value != _PetName)  
                       {  
                           _PetName = value;  
                       }  
                   }  
               }  
         
               public PetDetailsPage()  
               {  
                   InitializeComponent();  
                   
         
               }  
         
               protected override void OnAppearing()  
               {  
                   base.OnAppearing();  
                   RetrivePetInfo();  
               }  
               private async void RetrivePetInfo()  
               {  
                   var pet =  firebaseHelper.GetPet(PetName);  
                   if (pet != null)  
                   {  
                       petname.Text = pet.PetName;  
                   }  
         
               }  
           }  
       }  
    

    For more navigate details in Shell, you can refer to this thread:

    https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation#pass-data

    Here is running screenshot.

    105919-image.png After click the viewProfile 105926-image.png

    Best Regards,

    Leon Lu


    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.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

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