48

I am working on cross platform xamarin application and I want to create hyperlink label for "Forgot password?" on login page. I have used following code to create label but I don't know how to create onclick event on it.

 MainPage = new ContentPage
            {
                BackgroundImage = "background.png",
                Content = new StackLayout
                {
                    VerticalOptions = LayoutOptions.CenterAndExpand,
                    HorizontalOptions = LayoutOptions.CenterAndExpand,
                    Spacing = 50,
                    Children = {

                        new Label {
                            HorizontalTextAlignment = TextAlignment.Center,
                            Text = "Welcome, Please Sign in!",
                            FontSize=50,
                            TextColor=Color.Gray,
                        },


                         new Entry
                        {
                             Placeholder="Username",
                            VerticalOptions = LayoutOptions.Center,
                            Keyboard = Keyboard.Text,
                            HorizontalOptions = LayoutOptions.Center,
                             WidthRequest = 350,
                             HeightRequest = 50,
                             FontSize=20,
                             TextColor=Color.Gray,
                             PlaceholderColor=Color.Gray,
                        },

                          new Entry
                        {
                             Placeholder="Password",
                            VerticalOptions = LayoutOptions.Center,

                            Keyboard = Keyboard.Text,
                            HorizontalOptions = LayoutOptions.Center,
                             WidthRequest = 350,
                             HeightRequest = 50,
                             FontSize=25,
                             TextColor=Color.Gray,
                             IsPassword=true,
                              PlaceholderColor =Color.Gray,
                        },
                        new Button
                        {
                            Text="Login",
                            FontSize=Device.GetNamedSize(NamedSize.Large,typeof(Button)),
                            HorizontalOptions=LayoutOptions.Center,
                            VerticalOptions=LayoutOptions.Fill,
                            WidthRequest=350,
                            TextColor=Color.Silver,
                            BackgroundColor=Color.Red,
                            BorderColor=Color.Red,
                        },
                       new Label //for this label I want to create click event to open new page
                        {
                            Text="Forgot Password?",
                            FontSize=20,
                            TextColor=Color.Blue,
                            HorizontalOptions=LayoutOptions.Center,

                        },
                    } 
        }
            };
Curiosity
  • 1,753
  • 3
  • 25
  • 46
Dipak
  • 1,199
  • 4
  • 21
  • 43
  • I'm having a similar but not exactly the same problem here https://stackoverflow.com/questions/67686485/is-there-a-way-to-add-the-mouse-event-to-an-action-in-interface-builder. Any suggestions? – 1.21 gigawatts May 26 '21 at 01:37

4 Answers4

81

For people who prefer to use XAML and who like to bind Command directly to the ViewModel, you can use this:

<Label HorizontalOptions="Center"
       TextColor="Blue"
       FontSize="20"
       Text="Forgot Password?">
    <Label.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding ForgotPasswordCommand}" />
    </Label.GestureRecognizers>
</Label>

And then in your ViewModel, you'll just assign the command to your function:

public ICommand ForgotPasswordCommand => new Command(OnForgotPassword);

And then define the function with all the work get done:

private async void OnForgotPassword()
{ ... }

PS: You will need to declare that you are using System.Windows.Input;

Saamer
  • 4,687
  • 1
  • 13
  • 55
Mik
  • 1,306
  • 1
  • 10
  • 14
  • 1
    This is the simples approach, pure XAML, exactly what I needed. Thank you! – VPetrovic May 19 '19 at 00:12
  • I'm having a similar but not exactly the same problem here https://stackoverflow.com/questions/67686485/is-there-a-way-to-add-the-mouse-event-to-an-action-in-interface-builder. I want to get the event so I can see if CTRL button is held down when click. I've been using Interface builder but I can see the IAction event in the ViewController.h code. – 1.21 gigawatts May 26 '21 at 01:36
  • 2
    Good solution. If you want manage event in xaml.cs instead "ViewModel" you can use "Tapped" property. Es. – Ricko.. Mar 03 '22 at 16:09
40

Try this :

var forgetPasswordLabel = new Label   // Your Forget Password Label
{
    Text = "Forgot Password?",
    FontSize = 20,
    TextColor = Color.Blue,
    HorizontalOptions = LayoutOptions.Center,
};


// Your label tap event
var forgetPassword_tap = new TapGestureRecognizer();   
forgetPassword_tap.Tapped += (s,e) =>
{
    //
    //  Do your work here.
    //
};
forgetPasswordLabel.GestureRecognizers.Add(forgetPassword_tap);

Sample :

var forgetPasswordLabel = new Label   // Your Forget Password Label
{
    Text = "Forgot Password?",
    FontSize = 20,
    TextColor = Color.Blue,
    HorizontalOptions = LayoutOptions.Center,
};

MainPage = new ContentPage
{
    BackgroundImage = "background.png",
    Content = new StackLayout
    {
        VerticalOptions = LayoutOptions.CenterAndExpand,
        HorizontalOptions = LayoutOptions.CenterAndExpand,
        Spacing = 50,
        Children = {

            new Label {
                //HorizontalTextAlignment = TextAlignment.Center,
                Text = "Welcome, Please Sign in!",
                FontSize=50,
                TextColor=Color.Gray,
            },


            new Entry
            {
                Placeholder="Username",
                VerticalOptions = LayoutOptions.Center,
                Keyboard = Keyboard.Text,
                HorizontalOptions = LayoutOptions.Center,
                WidthRequest = 350,
                HeightRequest = 50,
                FontSize=20,
                TextColor=Color.Gray,
                PlaceholderColor=Color.Gray,
            },

            new Entry
            {
                Placeholder="Password",
                VerticalOptions = LayoutOptions.Center,

                Keyboard = Keyboard.Text,
                HorizontalOptions = LayoutOptions.Center,
                WidthRequest = 350,
                HeightRequest = 50,
                FontSize=25,
                TextColor=Color.Gray,
                IsPassword=true,
                PlaceholderColor =Color.Gray,
            },
            new Button
            {
                Text="Login",
                FontSize=Device.GetNamedSize(NamedSize.Large,typeof(Button)),
                HorizontalOptions=LayoutOptions.Center,
                VerticalOptions=LayoutOptions.Fill,
                WidthRequest=350,
                TextColor=Color.Silver,
                BackgroundColor=Color.Red,
                BorderColor=Color.Red,
            },
            forgetPasswordLabel
        }
    }
};

var forgetPassword_tap = new TapGestureRecognizer();
forgetPassword_tap.Tapped += (s,e) =>
{
    //
    //  Do your work here.
    //
};
forgetPasswordLabel.GestureRecognizers.Add(forgetPassword_tap);
codersl
  • 2,222
  • 4
  • 30
  • 33
Yksh
  • 3,276
  • 10
  • 56
  • 101
5

If the're several places with clickable Label, it makes sense to create a control inheriting from Xamarin.Forms Label and DO NOT PUT TapGestureRecognizer everywhere the label is required.

public class ExtendedLabel : Label
{
    private event EventHandler click;

    public string Name
    {
        get; set;
    }

    public void DoClick()
    {
        click?.Invoke(this, null);
    }

    public event EventHandler Clicked
    {
        add
        {
            lock (this)
            {
                click += value;

                var g = new TapGestureRecognizer();

                g.Tapped += (s, e) => click?.Invoke(s, e);

                GestureRecognizers.Add(g);
            }
        }
        remove
        {
            lock (this)
            {
                click -= value;

                GestureRecognizers.Clear();
            }
        }
    }
}    

In your XAML file you import the namespace where the control is defined, e.g.

<ContentPage xmlns:ctrl="clr-namespace:UICore.Controls" ...

And use it as ordinary control:

<ctrl:ExtendedLabel x:Name="quitButton" Clicked="OnQuit">
Maxim Saplin
  • 4,115
  • 38
  • 29
  • `click?.Invoke(this, null);` Would be safer – apex39 Aug 28 '19 at 14:07
  • 1
    Fixed the post. Thanks! – Maxim Saplin Aug 28 '19 at 14:22
  • I don't know why the label type doesn't inherently have an implementation for an on_click event handler. I plan on having multiple labels throughout my application with on_click events so this is great! – SendETHToThisAddress May 25 '20 at 07:12
  • This worked in Maui, though I'm not sure how to access the label text or underlying object. I used private void OnQuit(object sender, EventArgs e) { Console.WriteLine($"Peripheral clicked {(Label)sender.Text}"); } in my code behind. – gfmoore Jun 10 '22 at 17:01
3
MyClickyLabel.GestureRecognizers.Add(
    new TapGestureRecognizer() { 
        Command = new Command(() => { 
            /* Handle the click here */
        } )
    }
);
noelicus
  • 14,468
  • 3
  • 92
  • 111
  • Sorry, but this code is not working for me, what could the reason be? `lblLogin.GestureRecognizers.Add(new TapGestureRecognizer(){Command = new Command(() => {lblLogin_Clicked();})});` `private async void lblLogin_Clicked(){await Navigation.PushAsync(new LoginPage());}` – Abozanona Oct 21 '16 at 10:00
  • What happens if you you don't make lblLogin async? Or make your command async and await on lblLogin? – noelicus Oct 24 '16 at 09:49