I have the following app which has a CollectionView populated from an SQLite database, but I am having difficulty passing the selected value from the CollectionView to another page when clicked on.
Records.cs
using SQLite;
namespace b_records.Models
{
[Table("records)")]
public class Record
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[MaxLength(250)]
public string Amount { get; set; }
}
}
AppShell.xaml.cs
namespace b_records;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute("DetailPage", typeof(DetailPage));
}
}
MainPage.xaml
<CollectionView x:Name="recordList" Grid.Row="5" SelectionChanged="OnCollectionViewSelectionChanged" SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Id}" />
<Label Grid.Column="1" Text="{Binding Amount}" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
MainPage.xaml.cs
private async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
int id = (e.CurrentSelection.FirstOrDefault() as Record).Id;
await Shell.Current.GoToAsync($"DetailPage?id={id}");
}
DetailPage.xaml.cs
namespace b_records;
[QueryProperty(nameof(id), "id")]
public partial class DetailPage : ContentPage
{
public int id { get; set; }
public DetailPage()
{
InitializeComponent();
lblText.Text = id.ToString();
}
}
Trying to follow the details from Microsoft's documentation here: https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation?view=net-maui-6.0#pass-data
But each time I click on the CollectionView, I am taken to DetailPage, and the value in the lblText.text is 0 instead of the id value on the row in the CollectionView populated from the SQLite database.
Any idea why?
CodePudding user response:
The constructor is the first thing called when any object is created. (With possible exception of initialization values directly on data members.) NO property values have been set at that time. Thus, id
has not been set.
One solution is to move any code that needs any query value, into override of OnAppearing:
protected override void OnAppearing()
{
base.OnAppearing();
lblText.Text = id.ToString();
}
Alternative solution is to move that line into property setter:
public int id {
get => _id;
set
{
SetProperty(ref _id, value);
lblText.Text = value.ToString();
}
}
private int _id;
CodePudding user response:
Yes, the constructor of page DetailPage
is called before getting the passed value id
.
public DetailPage()
{
InitializeComponent();
lblText.Text = id.ToString();
}
So, you can try the following code:
[QueryProperty(nameof(id), "id")]
public partial class DetailPage : ContentPage
{
//public string id { get; set; }
public int id
{
set
{
LoadDetail(value);
}
}
public DetailPage()
{
InitializeComponent();
//lblText.Text = id.ToString();
}
void LoadDetail(int id)
{
try
{
lblText.Text = id.ToString();
}
catch (Exception)
{
Console.WriteLine("Failed.");
}
}
}