Segamoto Segamoto - 18 days ago 10
Objective-C Question

Tap Gesture Gesture Recognizer in ListView not working

I have this in my ViewModel:

public class MyClass: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
int taps = 0;
ICommand tapCommand;

public MyClass()
{
tapCommand = new Command(OnTapped);
}

public ICommand TapCommand
{
get { return tapCommand; }
}

void OnTapped(object s)
{
taps++;
Debug.WriteLine("parameter: " + s);
}
}


and this in the xaml:

<Image Source="delete.jpg" HeightRequest="20" WidthRequest="20">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding TapCommand}"
CommandParameter="Image1" />
</Image.GestureRecognizers>
</Image>


but when the image is clicked nothing appears in output log. What I'm missing ?


Note 1: I've followed the guide here

Note 2: I'm debugging on Android Device

Update 1: full xaml here

Answer

You have not provided any code behind, so I had to create my own (see below). You also would save me 15 minutes if commented out ListView IsEnabled="False"

When you set Command="{Binding TapCommand} the TapCommand corresponds to the TapCommand of the list item, not to the model itself. So, you have 2 options

  1. You can implement click in MyItem (I don't think you want that, so partial code for it commented below in MyItem class)
  2. Define context binding on image itself. Because of that our view model can be created few times - we don't want that, so the best solution is to define static resource of view model and use it everywhere on page. The solution is below (you will just need to modify some namespaces and change delte.png to your delete.jpg):

page xml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ButtonRendererDemo;assembly=ButtonRendererDemo"
             x:Class="ButtonRendererDemo.ImageTapComplexPage"
             BindingContext="{StaticResource viewModel}">

      <ContentPage.Resources>
        <ResourceDictionary>
          <local:TapComplexViewModel x:Key="viewModel"/>
        </ResourceDictionary>
      </ContentPage.Resources>


 <StackLayout>
    <Label Text="text2" VerticalOptions="Center" HorizontalOptions="Center" />
    <StackLayout Padding="0,20,0,20">
    <Button Text="text" Clicked="onclick" BackgroundColor="#009688"></Button>

    </StackLayout>
    <Label Text="List Type" VerticalOptions="Center" HorizontalOptions="Center" />
    <ListView x:Name="lstItems" RowHeight="60" ItemsSource="{Binding Items}" > <!--IsEnabled="False"-->
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <StackLayout Orientation="Horizontal" HorizontalOptions="Fill" Padding="0,2,0,2">
              <StackLayout Padding="5,5,5,5">
                <Image Source="{Binding source}" HorizontalOptions="End" HeightRequest="40" WidthRequest="40" />
              </StackLayout>
              <StackLayout Orientation="Vertical" Spacing="1">
                <Label Text = "{Binding name}" HeightRequest="20" FontAttributes="Bold"/>
                <Label Text = "{Binding data, StringFormat='{0:F0}'}" />
              </StackLayout>
              <StackLayout HorizontalOptions="EndAndExpand" Padding="0,0,15,0" Orientation="Horizontal">
                <Image Source="delete.png" HeightRequest="20" WidthRequest="20">
                   <Image.GestureRecognizers>
                    <!--<TapGestureRecognizer 
                        Command="{Binding TapCommand}"
                        CommandParameter="Image1" />-->
                        <TapGestureRecognizer Command="{Binding Source={StaticResource viewModel}, Path=TapCommand}" CommandParameter="{Binding name}" />
                 </Image.GestureRecognizers>
                </Image>
              </StackLayout>
            </StackLayout>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </StackLayout>
</ContentPage>

Code behind

namespace ButtonRendererDemo
{
    public partial class ImageTapComplexPage : ContentPage
    {
        public ImageTapComplexPage()
        {
            InitializeComponent();        
        }

        void onclick(object sender, EventArgs args)
        {

        }
    }

    public class TapComplexViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        int taps = 0;
        ICommand tapCommand;

        public ObservableCollection<MyItem> Items { get; private set; }
        public TapComplexViewModel()
        {
            Items = new ObservableCollection<MyItem>()
            {
                new MyItem { name="First", source="Icon.png", data=0.5f },
                new MyItem { name="Second", source="Icon.png", data=0.6f },
                new MyItem { name="Third", source="Icon.png", data=0.7f }
            };

            tapCommand = new Command(OnTapped);
        }

        public ICommand TapCommand
        {
            get { return tapCommand; }
        }

        void OnTapped(object s)
        {
            taps++;
            Debug.WriteLine("parameter: " + s);
        }



    }

    public class MyItem
    {
        public string name { get; set; }
        public string source { get; set; }
        public float data { get; set; }

        //public ICommand TapCommand
        //{
        //    get { return new Command(() => { }); }
        //}
    }
}

enter image description here