Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 75885

Use Custom Renderer for Label when Text is set via binding

$
0
0

Hi everyone.

I'm developing a cross platform app using Xamarin.Forms and Prism. I'm targeting both Android and iOS. The Android version has been realeased for a couple of months and is stable and fine - no issues there. The iOS version has been started recently and everything is working as expected apart from an issue related to custom label renderers. Sometimes they will work fine and other times they will not work at all

My Problem

I have added the font files to my resources folder and have set the build action to "BundleResource".

Please see an example of my code below.

My custom renderer for a label looks like this.

C#

class CustomLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                if (e.NewElement != null)
                {
                    try
                    {
                     Control.Font = UIFont.FromName(@"OpenSans-Regular", (nfloat)e.NewElement.FontSize);
                    }
                    catch (Exception ex)
                    {

                    }
                }
         }
        }
    }

The Try/Catch block is just there for my own sanity at this point

To my knowledge there is nothing wrong with how I have implemented this, I have done essentially the same thing for the Android version of the app and it works without issue.

Where this gets weird for me is here, here are two examples from one of my views

XAML

<cc:CustomLabel FontSize="Medium"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
Text="Homepage"
TextColor="White" />

XAML

<cc:CustomLabel FontSize="Small"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
Text="{Binding CountOfLeadsToActionLabel}"
TextColor="Black" />

In the first example, the catch will not be hit, the label will render with the custom font correctly and it looks fine. In the second example, the only thing that is different is that the text is set to the result of a database call in the ViewModel wired to the View, yet the catch will be hit & the following exception will be thrown.

{System.ArgumentNullException: Value cannot be null.
Parameter name: value
at UIKit.UILabel.set_Font (UIKit.UIFont value) [0x0003b] in /Users/builder/data/lanes/3988/e02d2723/source/xamarin-macios/src/build/ios/native/UIKit/UILabel.g.cs:370
at Onsight.iOS.Renderers.CustomLabelRenderer.OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1[TElement] e) [0x00026] in D:\Development\CRM Suite\MobileCRM\Onsight\Onsight.iOS\Renderers\CustomLabelRenderer.cs:26 }

Here is an example of the property in question, its nothing special. Just a standard property with the Prism magic applied to it

    private string _countOfLeadsToActionLabel;

    public string CountOfLeadsToActionLabel
    {
        get { return _countOfLeadsToActionLabel; }
        set { SetProperty(ref _countOfLeadsToActionLabel, value); }
    }

What I have attempted

In the constructor of the relevant ViewModel I have attempted to assign a default value of String.Empty to the property. I thought it might of had something to do with the value being null, this had no effect.

Created a static class to hold this value and bound the Text property of the cc:CustomLabel to the said property in the static class like so

<cc:CustomLabel FontSize="Small"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
    Text="{x:Static stringResolver:StringResolver.CountOfLeadsToActionLabel}"
TextColor="Black" />

This worked however, it seems very unnecessary and would be a complete pain in the arse to implement across the whole app, since it works perfectly fine on the Android version.

I'm no expert (yet) but based on this my guess is that the problem is occurring because the native UIKit.UILabel is being rendered before the text property is being set and this is causing some sort of error.

Has anyone ever come across this, or something similar? If so, could you share what you did to resolve it? Its not a huge problem as I can handle the error when it occurs and use the default platform font instead. It just means the Android and iOS version look a weird sat side by side.

Thanks in advance for any suggestions.


Viewing all articles
Browse latest Browse all 75885

Trending Articles