2
votes

I use images in the navigation bar using the TitleView Layout. It works BUT ...

I encounter problem to set the size of the image according to the Height of the navigation bar.

<NavigationPage.TitleView>
    <StackLayout Orientation="Horizontal"
                 VerticalOptions="Center"
                 Spacing="10">

        <Image Source="flechegauche.png" BindingContext="{x:Reference TitleLabel}" HeightRequest="{Binding Height}"/>

        <Label x:Name="TitleLabel" Text="Evènements" FontSize="16" TextColor="White" 
               VerticalTextAlignment="Center" VerticalOptions="FillAndExpand"
               HorizontalTextAlignment="Center" HorizontalOptions="FillAndExpand" />

        <Image Source="filtre.png" HeightRequest="{OnPlatform iOS=60, Android=35, Default=40}"/>
        <Image Source="flechedroite.png" HeightRequest="{OnPlatform iOS=60, Android=35, Default=40}"/>

    </StackLayout>
</NavigationPage.TitleView>

It works if i use : HeightRequest="{OnPlatform iOS=60, Android=35, Default=40}"

But this doen't work : BindingContext="{x:Reference TitleLabel}" HeightRequest="{Binding Height}"

Why ?!? It's still the best way to link the height of the image to the height of the navigation bar (to ensure that the image correctly fit), isn't it ?

I also tried setting "Aspect" to "AspectFit" but it doesn't change anything.

2
Even with binding like HeightRequest="{Binding Source={x:Reference TitleLabel}, Path=Height}" it doesn't works - Belight
Does not VerticalOptions="FillAndExpand" on the Image work? - pinedax

2 Answers

0
votes

I don't know why but I found this. I have created a converter like this:

class dblMultiplier : IValueConverter, IMarkupExtension
{
    public double Multiplier { get; set; } = 1.0f;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return System.Convert.ToDouble(value) * Multiplier;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException("Only one way bindings are supported with this converter");
    }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

And I use this binding in the XAML:

<Image Source="flechegauche.png" HeightRequest="{Binding Source={x:Reference TitleLabel}, Path=Height, Converter={Helpers:dblMultiplier Multiplier=0.99}}"/>

The converter is called two times. One with a default value of -1 when the height of the label isn't fixed yet. And the second when the layout is computed. So it works perfectly.

But if I use the same converter with 1.0 instead of 0.99, it doesn't work !!! The size of the image is not adapted ... ?!? Strange isn't it ?

0
votes

Ok, I found the core issue(s)...

(1) My image is too big at the first appearance (before the layout is computed), so the label which is referred to for scaling the image is not displayed, so the label can't serve for scaling the image, and the image do not display which the expected size !

So, I made a converter to force a small default value at the beginning:

class dblMultiplier : IValueConverter, IMarkupExtension
{
    public double Multiplier { get; set; } = 1.0f;
    public double Default { get; set; } = double.NaN;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double dvalue = System.Convert.ToDouble(value);

        if (dvalue < 0.0f && !double.IsNaN(Default) )
            return Default;

        return dvalue * Multiplier;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException("Only one way bindings are supported with this converter");
    }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

And I changed the XAML like this:

<Image Source="flechegauche.png" HeightRequest="{Binding Source={x:Reference TitleLabel}, Path=Height, Converter={Helpers:dblMultiplier Default=10}}"/>

(2) I had also to ensure that the label doesn't fit to whole height of the TitleView. Otherwise no scaling happens.