André Krämers Blog

Lösungen für Ihre Probleme

Während eines Prototypworkshops fragte mich ein Kunde kürzlich, warum das Xamarin.Forms Label Steuerelement kein Click oder Tap Ereignis veröffentlicht.

Die Antwort darauf ist relativ einfach:

Die meisten Xamarin.Forms Steuerelemente veröffentlichen selbst kein Clickoder Tap Ereignis. Stattdessen nutzt man in einem solchen Fall einen Tap Gesture Gesture Recognizer.

Über Tap Gesture Recognizer kann so ziemliches jedes Steuerelement klickbar gemacht werden.

Klicks / Taps mit Event Handlern

In einem kleinen Beispiel sieht das ganze wie folgt aus:

<ContentPage.Content>
    <StackLayout>
        <Label x:Name="NumberOfClicksLabel"></Label>
        <Label Text="Klick mich!">
            <Label.GestureRecognizers>
                <TapGestureRecognizer Tapped="KlickMichTapped"/>
            </Label.GestureRecognizers>
        </Label>
    </StackLayout>
</ContentPage.Content>

Im Quelltext definiere ich zunächst ein StackLayout, das zwei Labels beherbergt. Das obere der beiden Labels stellt später die Anzahl der Klicks dar, auf das untere wird zum Hochzählen geklickt. Wie man im Beispiel sieht, besitzt das Label eine Eigenschaft GestureRecognizer. Bei dieser Eigenschaft handelt es sich um eine Auflistung von registrierten Gesten. Der TapGestureRecognizer, über den das Label klickbar gemacht wird, wird einfach zur GestureRecognizer Auflistung hinzugefügt. Anschließend wird noch definiert, dass das Ereignis Tapped durch die Methode KlickMichTapped behandelt wird.

Die Methode KlickMichTapped befindet sich im Code-Behind meiner Seite:

public partial class MyPage : ContentPage
{

    public MyPage()
    {
        InitializeComponent();
    }

    private int _numberOfClicks = 0;
    private void KlickMichTapped(object sender, EventArgs e)
    {
        _numberOfClicks++;
        NumberOfClicksLabel.Text = $"{_numberOfClicks} Klicks";
    }
}

Klicks / Taps, Commands und MVVM

Wer statt Code-Behind lieber das Model-View-ViewModel Muster einsetzt, kann natürlich auch hier TapGestureRecognizer nutzen.

Das entsprechende ViewModel dazu sieht so aus:

public class TapDemoViewModel : INotifyPropertyChanged
{
    public Command TapCommand { get; set; }

    public TapDemoViewModel()
    {
        TapCommand = new Command(() => OnTapped());
    }

    private void OnTapped()
    {
        NumberOfClicks++;
    }

    private int _numberOfClicks;
    public int NumberOfClicks
    {
        get { return _numberOfClicks; }
        set
        {
            OnPropertyChanged();
            _numberOfClicks = value;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Innerhalb des ViewModels werden das Command TapCommand definiert sowie die Eigenschaft NumberOfClicks. Für das TapCommand wird die Methode OnTapped hinterlegt. Diese erhöht den Wert der Eigenschaft NumberOfClicks.

Im XAML Code wird nun an die Eigenschaft Text des ersten Labels die Eigenschaft NumberOfClicks des ViewModels gebunden. Das im ViewModel definierte Command TapCommand wird wiederum an die Eigenschaft Command des TapGestureRecognizer gebunden.

<ContentPage.Content>
    <StackLayout>
        <Label Text="{Binding NumberOfClicks, StringFormat='{0} Klicks'}}">
        </Label>
        <Label Text="Klick mich">
            <Label.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding TapCommand}" />
            </Label.GestureRecognizers>
        </Label>
    </StackLayout>
</ContentPage.Content>

Die Verbindung zwischen ViewModel und View wird schlussendlich im Code Behind des Views über die Zuweisung der Eigenschaft BindingContext erledigt.

public partial class TapDemo : ContentPage
{
    public TapDemo()
    {
        InitializeComponent();
        BindingContext = new TapDemoViewModel();
    }
}

In Aktion sieht die App dann wie folgt aus:

Ein Xamarin.Forms Label, klickbar durch Tap Gesture Recognizer

Fazit

Wie wir in diesem Beitrag gesehen haben, kann mit der Hilfe eines TapGestureRecognizer so ziemliches jedes Oberflächenelement unter Xamarin.Forms mit einem Click / Tap Ereignis ausgestattet werden. Neben dem TapGestureRecognizer gibt es übrigens auch noch den Pinch Gesture Recognizer und den Pan Gesture Recognizer