24

I basically want to create a hyperlink in Xamarin.Forms using the label class. Basically, I want to following link to take the user to google.com in a web browser:

<Label Text="http://www.google.com/" />

I can't find anything in the Xamarin Forms API about this and the internet has vague and limited information on this topic in Xamarin.Forms.

Is this possible? If so, could someone please point me in the right direction? Thanks in advance to anyone who answers.

Cfun
  • 8,442
  • 4
  • 30
  • 62
jnel899
  • 563
  • 2
  • 8
  • 21
  • 1
    There aren't links per se on Xamarin Forms, just add a GestureListener to the label and launch the browser by yourself. – Gusman Jun 02 '16 at 17:04
  • 2
    Possible duplicate of [HyperlinkButton in C# XAMARIN.FORMS](http://stackoverflow.com/questions/34739684/hyperlinkbutton-in-c-sharp-xamarin-forms) – JKennedy Jun 03 '16 at 07:56
  • https://stackoverflow.com/a/59255100/340628 The TapGestureRecognizer accepts also a command. Nice solution purely template based. – HCL Sep 26 '21 at 12:29

5 Answers5

23

You can't really do this because Labels by default don't respond to user input, but you can achieve something similar with gestures

using Xamarin.Forms;
using Xamarin.Essentials;

Label label = new Label();
label.Text = "http://www.google.com/";

var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += async (s, e) => {
    // Depreciated - Device.OpenUri( new Uri((Label)s).Text); 
    await Launcher.OpenAsync(new Uri(((Label)s).Text));
};
label.GestureRecognizers.Add(tapGestureRecognizer);
jnel899
  • 563
  • 2
  • 8
  • 21
Jason
  • 86,222
  • 15
  • 131
  • 146
  • 1
    Thanks a bunch! There is a small correction I needed to make: its actually `Device.OpenUri(new Uri(((Label)s).Text));` the `new Uri(uriString)` constructor is necessary to initialize the string as a Uri. Thank you after that change it worked! – jnel899 Jun 02 '16 at 18:30
  • 1
    As OpenUri is deprecated, you should now write `Launcher.OpenAsync(new Uri((s as Label).Text));` – Adriano Dec 16 '19 at 12:46
  • @Adriano Thank you - I have submitted an edit reflecting this – jnel899 Jun 11 '20 at 17:00
10

I made this little class to handle it:

public class SimpleLinkLabel : Label
{
    public SimpleLinkLabel(Uri uri, string labelText = null)
    {
        Text = labelText ?? uri.ToString();
        TextColor = Color.Blue;
        GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => Device.OpenUri(uri)) });
    }
}

And a bit more involved if you want to underline it too:

public class LinkLabel : StackLayout
{
    private SimpleLinkLabel label;

    public LinkLabel(Uri uri, string labelText = null, bool underlined = true)
    {
        // Remove bottom padding
        Padding = new Thickness(Padding.Left, Padding.Top, Padding.Right, 0);
        VerticalOptions = LayoutOptions.Center;

        Children.Add(label = new SimpleLinkLabel(uri, labelText));

        if (underlined)
            Children.Add(new BoxView { BackgroundColor = Color.Blue, HeightRequest = 1, Margin = new Thickness(0, -8, 0, 0) });
    }

    public TextAlignment HorizontalTextAlignment { get { return label.HorizontalTextAlignment; } set { label.HorizontalTextAlignment = value; } }
}

The latter class inspired by this post: how to underline in xamarin forms


Edit: XLabs have a HyperLinkLabel too.

noelicus
  • 14,468
  • 3
  • 92
  • 111
6
<Label LineBreakMode="WordWrap">
    <Label.FormattedText>
        <FormattedString>
            <Span Text="Google">
                <Span.GestureRecognizers>
                    <TapGestureRecognizer Tapped="Handle_Tapped" />
                </Span.GestureRecognizers>
            </Span>
        </FormattedString>
    </Label.FormattedText>
</Label>
public async void Handle_Tapped(object sender, EventArgs e)
{
    await Browser.OpenAsync(new Uri(url), BrowserLaunchMode.SystemPreferred);
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
user1924249
  • 540
  • 3
  • 13
  • 38
5

use a button and a xamarin.forms.theme nuget

<Button StyleClass = "Link"/>

https://developer.xamarin.com/guides/xamarin-forms/user-interface/themes/light/

Ahmed.Net
  • 158
  • 2
  • 6
3

If you want to do this with MVVM, you can create a Label with a blue text colour and a GestureRecognizers to hook it up to a Command:

<Label TextColor="Blue" Text="{Binding Model.LinkDescription}">
    <Label.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding ClickCommand}" CommandParameter="{Binding Model.LinkURL}"/>
    </Label.GestureRecognizers>
</Label>

In your ViewModel you can launch the default Browser using the Xamarin Essentials Nuget Package:

private Boolean IsValidUri(String uri)
{
    try
    {
        new Uri(uri);
        return true;
    }
    catch
    {
        return false;
    }
}

public ICommand ClickCommand => new Command<string>(async (url) =>
{
    try
    {
        if (!string.IsNullOrEmpty(url))
        {
            if (!url.Trim().StartsWith("http", StringComparison.OrdinalIgnoreCase))
            {
                url = "http://" + url;
            }
            if (IsValidUri(url))
            {
                await Browser.OpenAsync(new Uri(url), BrowserLaunchMode.SystemPreferred);
            }
        }
    }
    catch(Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }

});
Donal
  • 31,121
  • 10
  • 63
  • 72