Samantha J T Star
Samantha J T Star

Reputation: 32788

Can I use C# code to add a call to a command instead of a <Grid.GestureRecognizers>?

I have this code:

<ViewCell x:Name="co">
   <Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
      <Grid.GestureRecognizers>
         <TapGestureRecognizer Command="{Binding OpenPickerCommand}" CommandParameter="{x:Reference coPicker}" NumberOfTapsRequired="1" />
      </Grid.GestureRecognizers>
      <Picker x:Name="coPicker" IsVisible="false" HorizontalOptions="End" SelectedIndexChanged="coPickerSelectedIndexChanged" ItemsSource="{Binding Order}"></Picker>
      <Label x:Name="coLabel" HorizontalOptions="End"/>
   </Grid>
</ViewCell>

Is there a way that I can in C# connect up a command to the tapping of the cell rather than have to use the XAML <Grid.GestureRecognizers> ?

Upvotes: 1

Views: 1445

Answers (1)

Steven Thewissen
Steven Thewissen

Reputation: 2981

Adding a GestureRecognizer to a ViewCell is a big no-no. A ViewCell exists within a ListView or TableView which have more than enough tapped options of their own. Adding a GestureRecognizer might confuse the OS as to which tap it should handle.

Your options for the GestureRecognizer are basically the following 3, but I advise against them in a scenario where you have a ListView/TableView.

Check out some of the ListView/ViewCell based alternatives I mention below in your situation.


1. GestureRecognizer - Add it in code

var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (s, e) => {
    // handle the tap
};
myGrid.GestureRecognizers.Add(tapGestureRecognizer);

2. GestureRecognizer - Use a command

When you use MVVM you can also use a command binding in C#:

var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.SetBinding (TapGestureRecognizer.CommandProperty, "TapCommand");
myGrid.GestureRecognizers.Add(tapGestureRecognizer);

Which can then be bound in XAML:

<Grid>
    <Grid.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding TapCommand}" />
    </Grid.GestureRecognizers>
</Grid>

3. GestureRecognizer - Add it in XAML as you have done

<Grid>
      <Grid.GestureRecognizers>
         <TapGestureRecognizer Command="{Binding OpenPickerCommand}" CommandParameter="{x:Reference coPicker}" NumberOfTapsRequired="1" />
      </Grid.GestureRecognizers>
</Grid>

4. ViewCell - Tapped event

For the ViewCell you have a Tapped event:

<ViewCell Height="100" Tapped="OnTapped">
    <ViewCell.View>
        <StackLayout BackgroundColor="White" >
        </StackLayout>
    </ViewCell.View>
</ViewCell>

Which you can implement in code-behind:

void OnTapped (object sender, System.EventArgs e) { //your code}

5. ViewCell - Tapped command

When using MVVM you don't want to put a lot of business logic in the code-behind for your pages. In that case you can use a Behavior to convert the event to a command. A sample of that can be found here:

https://github.com/xamarin/xamarin-forms-samples/tree/master/Behaviors/EventToCommandBehavior/EventToCommandBehavior


6. ListView - ItemSelected

ListView itself also has an ItemSelected event. This can be handled the same way as the ViewCell Tapped event with both an event in code-behind or a Behavior to delegate it to a Command.

7. ListView - SelectedItem property

You can bind the SelectedItem to a property in your view model. On the setter you can perform your custom code.

<ListView
    ItemsSource="{Binding YourItems}"
    SelectedItem="{Binding YourSelectedItem, Mode=TwoWay}" >
</ListView>

And in code:

string _yourSelectedItem;
public string YourSelectedItem
{
    get { return _yourSelectedItem; }
    set {
        _yourSelectedItem = value;
        // Perform your custom functionality
    }
}

Upvotes: 7

Related Questions