Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a ListView with an ArrayAdapter set to it, and each row in the adapter contains four buttons that need to receive and handle click events. Normally in Android I would call SetOnClickListener on each button when I create the cell, but Mono gives the ability to set event handlers for the Click event instead. It looks like there's some weirdness to this in Mono though, because I run into one of two issues depending on where I set the event handler.

ArrayAdapter GetView Example 1:

View tweetCell = convertView;
if (tweetCell == null) {
    tweetCell = ((LayoutInflater)Context.GetSystemService (Context.LayoutInflaterService)).Inflate (Resource.Layout.TweetCell, null);

    tweetCell.FindViewById (Resource.Id.btn_moveTweet).Click += (object sender, EventArgs e) => MoveTweet (GetItem(position));

    tweetCell.FindViewById (Resource.Id.btn_unfavoriteTweet).Click += (object sender, EventArgs e) => UnfavoriteTweet (GetItem(position));

    tweetCell.FindViewById (Resource.Id.btn_hideTweet).Click += (object sender, EventArgs e) => HideTweet (GetItem(position));

    tweetCell.FindViewById (Resource.Id.btn_shareTweet).Click += (object sender, EventArgs e) => ShareTweet (GetItem(position));
}

Here, my event handler only gets set once per button (good!), but the position value is wrong most of the time. I'm wondering if the conversion from Mono to Android code is causing GetItem(position) to use the same value for position every time (the value that position is set to when the cell is first created). This code would work totally fine in normal Android.

ArrayAdapter GetView Example 2:

View tweetCell = convertView;
if (tweetCell == null) {
    tweetCell = ((LayoutInflater)Context.GetSystemService (Context.LayoutInflaterService)).Inflate (Resource.Layout.TweetCell, null);
}
tweetCell.FindViewById (Resource.Id.btn_moveTweet).Click += (object sender, EventArgs e) => MoveTweet (GetItem(position));

tweetCell.FindViewById (Resource.Id.btn_unfavoriteTweet).Click += (object sender, EventArgs e) => UnfavoriteTweet (GetItem(position));

tweetCell.FindViewById (Resource.Id.btn_hideTweet).Click += (object sender, EventArgs e) => HideTweet (GetItem(position));

tweetCell.FindViewById (Resource.Id.btn_shareTweet).Click += (object sender, EventArgs e) => ShareTweet (GetItem(position));

This method does cause the click event to be fired for the correct position, but it sets a new event handler every time the row is recycled. This causes click events for lots of rows at the same time. A workaround for this method would seem to be to keep references to the event handlers and remove them before setting them again inside GetView, but this seems extremely inelegant.

Is there a better method for handling click events inside ListView items in Monodroid?

share|improve this question

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.