Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tab icons in a Xamarin.Forms UWP TabbedPage?

When putting together a TabbedPage in Xamarin.Forms, how do I get UWP to use the page's Icon property?

It looks like UWP could support this just fine, if I configure my Forms attributes/files correctly.

Here's my TabbedPage XAML. The icons are all set up and working for iOS and Android, and even the on-page Image in UWP renders fine (meaning the files are likely in the project correctly).

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:tabbed"
             x:Class="tabbed.MainPage">
    <TabbedPage.Children>
        <local:InitialPage Title="Tab1" Icon="star.png" />
        <ContentPage Title="Tab2" Icon="gear.png">
            <ContentPage.Content>
                <StackLayout>
                    <Label Text="A nice label." />
                    <Image Source="star.png" /><!-- works here -->
                </StackLayout>
            </ContentPage.Content>
        </ContentPage>
    </TabbedPage.Children>
</TabbedPage>
like image 249
patridge Avatar asked Mar 08 '23 12:03

patridge


1 Answers

I outlined how this is possible here http://depblog.weblogs.us/2017/07/12/xamarin-forms-tabbed-page-uwp-with-images/

In short, you need to change the default HeaderTemplate that is being used by UWP. But due to the way Xamarin forms is started, this is not straightforward. So you need to inject a custom template into the resource dictionary.

Example project is up on Github here https://github.com/Depechie/XamarinFormsTabbedPageUWPWithIcons

Longer detail:

You need to supply your own TabbedPageStyle and switch out the one that Xamarin is using for their UWP rendering. So the new style contains an Image where we data bind the Source to the Xamarin Icon property.

<Style x:Key="TabbedPageStyle2" TargetType="uwp:FormsPivot">
    <Setter Property="HeaderTemplate">
        <Setter.Value>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <Image Source="{Binding Icon, Converter={StaticResource IconConverter}}" Width="15" Height="15" />
                    <TextBlock Name="TabbedPageHeaderTextBlock" Text="{Binding Title}"
                                Style="{ThemeResource BodyTextBlockStyle}" />
                </StackPanel>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

The actual style switching is done in the App.Xaml.cs like this

((Style)this.Resources["TabbedPageStyle"]).Setters[0] = ((Style)this.Resources["TabbedPageStyle2"]).Setters[0];

You'll also need a converter to be sure the Image control understands the Icon source giving by Xamarin

public class IconConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value != null && value is Xamarin.Forms.FileImageSource)
            return ((Xamarin.Forms.FileImageSource)value).File;

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
like image 69
Depechie Avatar answered Apr 06 '23 21:04

Depechie