I have a CollectionView 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 CollectionView. 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.
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;
}
}
private void Button_Clicked(object sender, EventArgs e)
{
}
}
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();
}
QueryPropertyattribute above the class .setmethod of properyPetNameis invoked later than class constructor, so_PetNameis null inRetrivePetInfomethod , as a workaround , you could callRetrivePetInfodirectly insetmethod instead in constructor .