I created an Enum type:
internal enum Routes
{
PageOne,
PageTwo,
}
In AppShell, I navigate from MainPage to another ShellContent (PageOne) using a button:
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}" />
<TabBar>
<Tab>
<ShellContent
Title="PageOne"
Route="PageOne"
ContentTemplate="{DataTemplate local:PageOne}" />
</Tab>
</TabBar>
So far everything works fine until I start doing this:
<TabBar>
<Tab>
<ShellContent
Title="PageOne"
Route="{Binding Source={x:Static local:Routes.PageOne}}"
ContentTemplate="{DataTemplate local:PageOne}" />
</Tab>
</TabBar>
The compiler throws the following error:
XamlC error XFC0009: No property, BindableProperty, or event found for "Route", or mismatching type between value and property.
What is puzzling me is that even though both the Title and Route properties are of type string, the Title property accepts the enum value just fine while the Route property doesn't. For example, the following block works as expected:
<ShellContent
Title="{Binding Source={x:Static local:Routes.PageOne}}"
Route="PageOne" />
Why the Route property does not accept the enum binding as the Title property does? And is there a workaround?
Update: I tried to workaround this by Self-binding the Route property to the Title property, to no avail:
<ShellContent
Title="PageOne"
Route="{Binding Source={RelativeSource Mode=Self}, Path=Title}"
ContentTemplate="{DataTemplate local:PageOne}" />
As a workaround you can use a static class instead of Enum:
public static class Routes
{
public static readonly string PageOne = nameof(Routes.PageOne);
public static readonly string PageTwo = nameof(Routes.PageTwo);
}
<ShellContent Title="{x:Static local:Routes.PageTwo}"
ContentTemplate="{DataTemplate local:PageTwo}"
Route="{x:Static local:Routes.PageTwo}" />
private async void OnClicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("///" + Routes.PageTwo);
}
Title is a bindable property while Route is just a string property. In other words, you can't bind to Route
(like what you tried with: Route="{Binding Source={x:Static local:Routes.PageOne}}"
.
From another side, Route="{x:Static local:RoutesEnum.PageTwo}"
is
not working because "mismatching type between value and property" Enum vs string, to make it work you need to explicitly cast/convert the enum value to a string using a markup extension (since binding+converter is not an option here):
public class EnumToStringExtension : IMarkupExtension
{
public RoutesEnum Value { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
=> Value.ToString();
}
Route="{local:EnumToString Value=PageTwo}"
Personal I would go with the first solution since it is simpler and safe (use of nameof).