Search code examples
c#event-handlingxamarin.formsextend

Extend Label control - adding a Click event handler


I need a control that can respond to both single click / tap and double click / tap. I found out I cannot use TapGestureRecognizer if I want to handle both single and double clicks / taps. So, I am trying to extend a Label control, adding a Click event handler. I tried the following code, but the event does not fire. Any suggestions? Thanks!

in LabelClickable.cs: ... public class LabelClickable : Label { public event EventHandler Clicked; public virtual void OnClicked() { Clicked?.Invoke(this, EventArgs.Empty); } } ...
in MainPage.XAML: ... <local:LabelClickable Text="0" Clicked="Button_Clicked"/> ...
and in MainPage.Xaml.cs: ... private void Button_Clicked(object sender, EventArgs e) { //do something; } ...


Solution

  • Here's the complete working solution (thanks for the suggestions Jason!):

    public class LabelClickable: Label
    {
        public LabelClickable()
        {
            TapGestureRecognizer singleTap = new TapGestureRecognizer()
            {
                NumberOfTapsRequired = 1
            };
            TapGestureRecognizer doubleTap = new TapGestureRecognizer()
            {
                NumberOfTapsRequired = 2
            };
            this.GestureRecognizers.Add(singleTap);
            this.GestureRecognizers.Add(doubleTap);
            singleTap.Tapped += Label_Clicked;
            doubleTap.Tapped += Label_Clicked;
        }
    
        private static int clickCount;
    
        private void Label_Clicked(object sender, EventArgs e)
        {
            if (clickCount < 1)
            {
                TimeSpan tt = new TimeSpan(0, 0, 0, 0, 250);
                Device.StartTimer(tt, ClickHandle);
            }
            clickCount++;
        }
    
        bool ClickHandle()
        {
            if (clickCount > 1)
            {
                Minus1();
            }
            else
            {
                Plus1();
            }
            clickCount = 0;
            return false;
        }
    
        private void Minus1()
        {
            int value = Convert.ToInt16(Text) - 1;
            if (value < 0)
                value = 0;
            Text = value.ToString();
        }
    
        private void Plus1()
        {
            Text = (Convert.ToInt16(Text) + 1).ToString();
        }
    }
    

    Usage on MainPage.xaml:

    <local:LabelClickable Text="0" Grid.Row="0" Grid.Column="0" BackgroundColor="Transparent" FontSize="Large" FontAttributes="Bold" HorizontalTextAlignment="Center"/>
    

    Nothing else is required on MainPage.xaml.cs.

    Works like a charm for both single and double taps! The result is a clickable label displaying a counter; the counter increments on a single tap and decrements on a double tap.