xamlxamarin.formsfont-awesomeeventtriggertabbedpage

Xamarin Forms Tabbed Page Trigger properties not working


I'm trying to follow this sample by using font awesome as icon for the tabbed page and use the triggers to change font color but when I want to apply the style using font awesome I got an error that Property="IsChecked" does not exist for the target. I noticed in the sample they are using shells how could I replicate that example using regular tabbed pages?

on the app.XAML I have the following

<OnPlatform x:TypeArguments="x:String" 
            x:Key="FontAwesomeSolid">
            <On Platform="Android" 
            Value="Font5Solid.otf#Regular" />
            <On Platform="iOS" 
            Value="FontAwesome5Free-Solid" />
         </OnPlatform>
         <OnPlatform x:TypeArguments="x:String" 
            x:Key="FontAwesomeRegular">
            <On Platform="Android" 
            Value="Font5Regular.otf#Regular" />
            <On Platform="iOS" 
             Value="FontAwesome5Free-Regular" />
          </OnPlatform>

For the tabbed page I have the following

<?xml version="1.0" encoding="utf-8"?>
<TabbedPage x:Name="Tab" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="pages.Views.HomeTabbedPage">
    <!--Pages can be added as references or inline-->

    <TabbedPage.Resources>
          <ResourceDictionary>
     <Style TargetType="Tab" x:Key="FollowTab">
                <Style.Triggers>
                <Trigger TargetType="TabbedPage"
                         Property="IsChecked" Value="False">
                    <Setter Property="Icon" >
                        <Setter.Value>
                            <FontImageSource FontFamily="{StaticResource FontAwesomeRegular}" Glyph="&#xf004;"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <Trigger TargetType="Tab" 
                         Property="IsChecked" Value="True">
                    <Setter Property="Icon" >
                        <Setter.Value>
                            <FontImageSource FontFamily="{StaticResource FontAwesomeSolid}" Glyph="&#xf004;"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                </Style.Triggers>
            </Style>
  </ResourceDictionary>
    </TabbedPage.Resources>

    <ContentPage Title="sample page"  />
    
</TabbedPage>

Solution

  • To replicate that in a normal TabbedPage you can try these steps:

    1 - Create a converter to check TabbedPage.CurrentPage type:

    public class SelectedTabTypeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return null;
    
            if (!(value is Page))
                throw new ArgumentException("Expected value to be of type " + nameof(Page), nameof(value));
    
            // if value is a NavigationPage check against its RootPage
            if (value is NavigationPage navPage)
                return navPage.RootPage?.GetType();
    
            return value.GetType();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
            => throw new NotImplementedException();
    }
    

    2 - Add the x:Name attribute to the TabbedPage so we can reference it latter:

    <TabbedPage x:Name="MyTabbedPage" ...
    

    3 - Add the converter resource to TabbedPage.Resources:

      <TabbedPage.Resources>
        <ResourceDictionary>
          <converters:SelectedTabTypeConverter x:Key="SelectedTabTypeConverter" />
        </ResourceDictionary>
      </TabbedPage.Resources>
    

    4 - Add the pages and the DataTriggers:

      <TabbedPage.Children>
        <!-- Normal page tab default values -->
        <views:OnePage Title="Page1">
          <views:OnePage.Triggers>
            <DataTrigger 
                TargetType="views:OnePage"
                Binding="{Binding Source={x:Reference MyTabbedPage}, Path=CurrentPage, Converter={StaticResource SelectedTabTypeConverter}}" 
                Value="{x:Type views:OnePage}">
              <Setter Property="Title" Value="Page1 Selected" />
            </DataTrigger>
          </views:OnePage.Triggers>
        </views:OnePage>
    
        <!-- NavigationPage tab -->
        <NavigationPage Title="Page2">
          <x:Arguments>
            <views:TwoPage />
          </x:Arguments>
          <NavigationPage.Triggers>
            <DataTrigger 
                TargetType="NavigationPage" 
                Binding="{Binding Source={x:Reference MyTabbedPage}, Path=CurrentPage, Converter={StaticResource SelectedTabTypeConverter}}" 
                Value="{x:Type views:TwoPage}">
              <Setter Property="Title" Value="Page2 Selected" />
            </DataTrigger>
          </NavigationPage.Triggers>
        </NavigationPage>
      </TabbedPage.Children>