Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

How to handle individual ViewCell clicking events once added to a ListView

FilipTodorovicFilipTodorovic USMember
edited August 2015 in Xamarin.Forms

So I have a ViewCell that displays some labels and two images, and I would like to make the ViewCell clickable and then handle what to do once the ViewCell is clicked. I would like to have one of the images change and then send something to a remote server via HTTP. I have the HTTP code set up, I just need to know where to put it. I have a main StackLayout within the ViewCell and I found that I can add a TapGestureRecognizer to the StackLayout's GestureRecognizers, but then how do I bind/reference the gesture to a function in the ContentPage where the ListView is displayed?

Here is my ContentPage:
public class ItemsPage : ContentPage
{
public string username { get; private set; }

    List<Event> itemList  = new List<Event>();
    ListView itemListView = new ListView();

    StackLayout itemListStack = new StackLayout();

    public ItemsPage(string username)
    {
        this.username   = username;
        BackgroundColor = Color.FromHex("#ececec");
        getItems();

        itemListView.HasUnevenRows = true;
        itemListView.ItemsSource   = eventsList;
        itemListView.ItemTemplate  = new DataTemplate(typeof(Item));

        // Add to Stack
        itemListStack.VerticalOptions = LayoutOptions.FillAndExpand;
        itemListStack.Children.Add(itemListView);

        Content = new StackLayout
        {
            Children = 
            {
                itemListStack,
            }
        };
    }

    // TEST
    private void getItems()
    {
        MyClient client = new MyClient();
        var myList = client.getItems(username);

        if (myList== null)
        {
            // do something else
        }
        else
        {
            foreach (Item item in myList)
            {
                var entry = new Item()
                {
                    userName    = item.userName,
                    description = item.description, // Must check if empty for visibility
                    location    = item.location,
                    time        = item.time,
                    icon        = item.icon
                };
                itemList.Add(entry);
            }
        }
    }

    public void OnItemClicked()
    {
        // here is where I would change an image of the specific ViewCell that was clicked
    }
}

Here is my ViewCell:
public class Item : ViewCell
{
// DECLARATIONS
Image image1 = new Image();
Image image2 = new Image();
StackLayout ItemStack;
... // other objects

    private readonly ItemsPage model;

    public EventsEntry(ItemsPage model)
    {
        this.model = model;
        // ------------------------------ PLACEHOLDERS ----------------------------------
        image1.Source = "image1.png";
        image2.Source = "image2.png";
        ... // other object's placeholders

        // --------------------------------- BINDING ------------------------------------
        image1.SetBinding(Label.TextProperty, "image1");
        image2.SetBinding(Label.TextProperty, "image2");
        ... // other bindings

        // --------------------------------- STYLES -------------------------------------
        ... // objects styling

        // ------------------------------ VISUAL LAYOUT ---------------------------------
        Grid itemGrid = new Grid
        {
            RowDefinitions =
            {
                new RowDefinition { Height = 5 },
                new RowDefinition { Height = 10 },
                new RowDefinition { Height = 10 },
                new RowDefinition { Height = 10 },
                new RowDefinition { Height = 10 },
            },

            ColumnDefinitions = 
            {
                new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
            },
        };

        itemGrid.RowSpacing    = 0;
        itemGrid.ColumnSpacing = 0;

        itemGrid.Children.Add(image1, 0, 1);
        Grid.SetRowSpan(image1, 4);

        itemGrid.Children.Add(image2, 0, 2);
        Grid.SetRowSpan(image2, 4);

        ... // other objects added to grid

        ItemStack = new StackLayout()
        {
            Orientation = StackOrientation.Vertical,
            Children    =
            {
                itemGrid,
                ... // other objects added to stacklayout
            }
        };
        ItemStack.BackgroundColor = Color.White;

        var itemClick = new TapGestureRecognizer();
        itemClick.Tapped += (s, e) => model.OnItemClicked();
        ItemStack.GestureRecognizers.Add(itemClick);

        this.View = ItemStack;
    }
}

I understand that the gesture can be added within the ViewCell, but how can I change an individual image within a ViewCell when it's clicked once the ContentPage has been populated with multiple ViewCell objects?

Answers

  • TorbenKruseTorbenKruse DEMember ✭✭✭

    I would use bindings and a Command when the cell gets tapped. It is probably not exactly what you are looking for, but it should give you an idea of how you can handle this. Have a look here.

Sign In or Register to comment.