1
votes

I have a ListView with custom cells. In each custom cell, the user can tap an ellipses looking image to invoke functionality in the cell. At this point I am focused on an aesthetic issue.

enter image description here

Notice I have implemented this with a Button containing an image with the ellipses. I used a Button because it natively responds to tap events. The problem is the button has a border. Also, the button has a tap animation that is less than desirable.

<ListView x:Name="___listview" HasUnevenRows="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal" Padding="10" Margin="10">
                    <Button Image="{Binding ImageName}" Command="{Binding UpCount}" 
                            BackgroundColor="White" WidthRequest="50" />
                    <Label Text="{Binding Count}" HorizontalOptions="CenterAndExpand" />
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Each ViewCell is bound to the following model.

public class Model : INotifyPropertyChanged
{
    public Model()
    {
        _count = 0;
        _imageName = "ellipses_vertical.png";
        UpCount = new Command(() =>
        {
            Count++;
            ImageName = (_imageName == "ellipses_vertical.png") 
                                    ? "ellipses_horizontal.png" 
                                    : "ellipses_vertical.png";
        });
    }

    int _count;
    public int Count
    {
        get { return _count; }
        set { if (_count != value) { _count = value; OnPropertyChanged("Count"); } }
    }

    string _imageName;
    public string ImageName
    {
        get { return _imageName; }
        set { if (_imageName != value) { _imageName = value; OnPropertyChanged("ImageName"); } }
    }

    public ICommand UpCount { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

I think what would work better is a simple Image in lieu of the Button. However, the Image has no native 'tap' handling or ICommand handling. Using a TapGestureRecognizer you can attach this type of behavior to other elements including an Image. The code would look something like this...

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

Each ViewCell has an Image for which this Gesture Recognizer would need to attach. However, I can't reference the Image by name in my model.

Is there a way enable a tap handler for each ViewCell's image and handle the tap in the Model (not code behind)?

1

1 Answers

1
votes

Yes you can add a TapGestureRecognizer in Xaml and recieve the command in the Viewmodel. For more information take a look at the Xamarin Documentation.

In your case it would look something like this.

<Image Source="{Binding ImageName}">
    <Image.GestureRecognizers>
        <TapGestureRecognizer
            Command="{Binding UpCount}" />
    </Image.GestureRecognizers>
</Image>