Search code examples
xamarinxamarin.formsuwptextblockxamarin.uwp

Xamarin.Forms UWP - InvalidCastException when trying to set TextDecorations for TextBlock


In a Xamarin.Forms project, I'm trying to allow underlined Labels. So I have a custom renderer, and I'm trying to do something simple:

Control.TextDecorations = TextDecorations.Underline;

It compiles just fine, but when the app launches, I'm getting an InvalidCastException on that line which says:

System.InvalidCastException: 'Unable to cast object of type 'Windows.UI.Xaml.Controls.TextBlock' to type 'Windows.UI.Xaml.Controls.ITextBlock5'.'

Here's a screenshot of the exception:

enter image description here

Also, when inspecting the Control, I noticed there are a ton of InvalidCastException exceptions on other properties of the TextBlock control as well - here's a small sample:

enter image description here

Why is it trying to cast to a ITextBlock5 type? Is this a UWP bug? Is there a workaround to get underline to work?


Solution

  • According to the Microsoft documentation, the TextDecorations property wasn't introduced until version 15063. You're probably getting that exception because you're on an earlier version of Windows.

    As a workaround, you can create an Underline() object and add a Run() object to the Underline object's Inlines collection, like this:

    // first clear control content
    Control.Inlines.Clear();
    
    // next create new Underline object and
    // add a new Run to its Inline collection
    var underlinedText = new Underline();
    underlinedText.Inlines.Add(new Run { Text = "text of xamarin element here" });
    
    // finally add the new Underline object
    // to the Control's Inline collection
    Control.Inlines.Add(underlinedText);
    

    Inside the custom renderer's OnElementChanged() override method, it would look something like this:

    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);
        var view = e.NewElement as LabelExt; // LabelExt => name of PCL custom Label class
        var elementExists = (view != null && Control != null);
        if (!elementExists)
        {
            return;
        }
    
        // add underline to label
        Control.Inlines.Clear();
        var underlinedText = new Underline();
        underlinedText.Inlines.Add(new Run { Text = view.Text });
        Control.Inlines.Add(underlinedText);
    }