Reputation:
I have been searching everywhere how to achieve passing parameters with shell navigation but I can't get this to work.
This is the line where I navigate to my InvoicePage
await Shell.Current.GoToAsync($"//main/InvoicePage?total ={ lblTotalCart.Text.Trim('€')}");
What I want is to be able to retrieve the value on my View Model but I'm trying at least on my ContentPage and it is not working.
[XamlCompilation(XamlCompilationOptions.Compile)]
[QueryProperty("Total", "total")]
public partial class InvoicePage : ContentPage
{
string total;
public string Total
{
set
{
total = Uri.UnescapeDataString(value ?? string.Empty);
OnPropertyChanged();
}
get
{
return total;
}
}
public InvoicePage()
{
InitializeComponent();
BindingContext = new InvoiceViewModel(Total);
}
Tried the same on my ViewModel and it is also not working.
Here is my View. I just have a Label to test it
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:AppCrijoya.ViewModels"
x:Class="AppCrijoya.Views.InvoicePage"
x:DataType="viewmodels:InvoiceViewModel">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding Total}"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
EDIT
I tried doing this on my ViewModel but it still doesn't return anything
[QueryProperty("Total", "Total")]
public class InvoiceViewModel : BindableObject
{
string _total;
public string Total
{
set
{
try
{
_total = Uri.UnescapeDataString(value);
OnPropertyChanged();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
get { return _total; }
}
}
Then on my InvoicePage
I have this
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class InvoicePage : ContentPage
{
public InvoicePage()
{
InitializeComponent();
BindingContext = new InvoiceViewModel();
}
}
I don't know if it is because of the route that is faling. Here is my AppShell
<TabBar Route="main">
<Tab Route="CategoryPage" Title="Explorar" Icon="tab_feed.png">
<ShellContent ContentTemplate="{DataTemplate local:CategoryPage}" />
</Tab>
<Tab Route="CartPage" Title="Carrito" Icon="tab_feed.png">
<ShellContent ContentTemplate="{DataTemplate local:CartPage}" />
</Tab>
<Tab Route="InvoicePage" Title="Factura" Icon="tab_feed.png">
<ShellContent ContentTemplate="{DataTemplate local:InvoicePage}" />
</Tab>
</TabBar>
And here are the routes I registered
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(CategoryPage), typeof(CategoryPage));
Routing.RegisterRoute(nameof(CartPage), typeof(CartPage));
Routing.RegisterRoute(nameof(InvoicePage), typeof(InvoicePage));
}
How can I achieve this? Please help, I don't know what else I can do. Thanks.
Upvotes: 2
Views: 2331
Reputation: 13823
The BindingContext
is not set at the right time in your code.
When we navigate to page InvoicePage
, above code is executed in the following order:
1.the constructor of page InvoicePage
public InvoicePage()
{
InitializeComponent();
//BindingContext = new InvoiceViewModel(Total);
}
2.get the passed data from previous page:
set
{
total = Uri.UnescapeDataString(value ?? string.Empty);
// other code
}
So, we should set the BindingContext
for page InvoicePage
after we get the passed data.
You can refer to the following code:
[XamlCompilation(XamlCompilationOptions.Compile)]
[QueryProperty("Total", "total")]
public partial class InvoicePage : ContentPage
{
string total;
public string Total
{
set
{
total = Uri.UnescapeDataString(value ?? string.Empty);
// here we can get the passed data and set the `BindingContext` for page `InvoicePage`
BindingContext = this;
// OnPropertyChanged();
}
get
{
return total;
}
}
public InvoicePage()
{
InitializeComponent();
}
// other code
}
Upvotes: 1