Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] Unable to select same item twice in a CollectionView #12491

Open
snowman745 opened this issue Oct 14, 2020 · 12 comments
Open

[Bug] Unable to select same item twice in a CollectionView #12491

snowman745 opened this issue Oct 14, 2020 · 12 comments

Comments

@snowman745
Copy link

snowman745 commented Oct 14, 2020

  1. Create a CollectionView setting SelectionMode = Single
  2. Add SelectionChanged event.
  3. Add one item to the CollectionView
  4. Select the item firing the SelectionChanged event.
  5. Select the item again.

Result: SelectionChanged event not fired.

Note: I even set SelectedItem = null but this does not help.

private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
FriendViewModel selectedItem = (FriendViewModel) FriendsCollectionView.SelectedItem;
if(selectedItem != null)
{
ViewFriend(selectedItem.FriendId);
FriendsCollectionView.SelectedItem = null;
}
}

Xamarin Forms version 4.8.0.1534
Visual Studio Version 16.7.5

NOTE: Repro'd on UWP, does NOT repro on Android.

Repro:
CollectionViewSingleSelectionDemo.zip

@snowman745 snowman745 added s/unverified New report that has yet to be verified t/bug 🐛 labels Oct 14, 2020
@rachelkang
Copy link
Contributor

Hi, @snowman745 - thanks for submitting this issue. The expected behavior for SelectionChanged is correct - it doesn't get fired if you select the same item twice since the selectedItem is already selected. The only way to fire SelectionChanged is to either (1) select a different item before selecting the item again, or (2) setting the selected item to null.

Try adding something like this in your SelectionChanged method instead: ((CollectionView)sender).SelectedItem = null;
or consider using TapGestureRecognizer if that better suits your use case! (related docs here: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/gestures/tap)

Closing this issue, but if I misunderstood what's happening, please feel free to reopen with a sample project attached! Thanks :)

@snowman745
Copy link
Author

Hi, as stated in my repro, I am setting selectedItem to null.

This is what's broken.

I even tried it as you stated:

((CollectionView)sender).SelectedItem = null;

@snowman745
Copy link
Author

How do I reopen this?

@rachelkang
Copy link
Contributor

@snowman745 Happy to keep looking at this! I followed the steps you described and was able to get it working with ((CollectionView)sender).SelectedItem = null;, and on the same version of XF as well. Could you attach a sample project that reproduces the issue, so that we can take a closer look at why it might not be working for you?

@rachelkang rachelkang reopened this Oct 14, 2020
@rachelkang rachelkang added s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/needs-repro ❔ This reported issue doesn't include a sample project reproducing the issue. Please provide one. labels Oct 14, 2020
@snowman745
Copy link
Author

Can you try your project on UWP? It tried and it works as expected on Android.

If you cannot repro on UWP, ill upload a sample project.

Thanks.

@Redth Redth removed s/needs-info ❓ A question has been asked that requires an answer before work can continue on this issue. s/needs-repro ❔ This reported issue doesn't include a sample project reproducing the issue. Please provide one. labels Oct 15, 2020
@rachelkang rachelkang added a/collectionview e/3 🕒 3 p/UWP and removed s/unverified New report that has yet to be verified labels Oct 16, 2020
@alihut
Copy link

alihut commented Nov 16, 2020

Can you try your project on UWP? It tried and it works as expected on Android.

If you cannot repro on UWP, ill upload a sample project.

Thanks.

Same problem here. Works on Android, not on UWP.

@snowman745
Copy link
Author

Any update on this?

@Agredo
Copy link

Agredo commented Aug 4, 2021

Hi is there a workaround? Or any Updated?

@everettpatel
Copy link

Hi, I have the same problem! this is a real issue on UWP

@AhmedAdelGadElkareeem
Copy link

Hi, I have the same problem! this is a real issue on UWP

@AhmedAdelGadElkareeem
Copy link

AhmedAdelGadElkareeem commented Jan 17, 2023

I solve this bug using stacklayout bindable items source and set gesture tapped for item

<StackLayout BindableLayout.ItemsSource="{Binding User.TopFollowers}"
Orientation="Horizontal"
...>
<BindableLayout.ItemTemplate>

<controls:CircleImage Source="{Binding}"
Aspect="AspectFill"
WidthRequest="44"
HeightRequest="44">
controls:CircleImage.GestureRecognizers

</controls:CircleImage.GestureRecognizers>
</controls:CircleImage>

</BindableLayout.ItemTemplate>

@Mimisss
Copy link

Mimisss commented Oct 6, 2023

@snowman745 This still exists in Xamarin.Forms 5.0.0.2012. @rachelkang I guess this is expected behavior.

The real problem is that every damned web page out there suggests the code below:

private void MyCollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        MyObject item = (MyObject)e.CurrentSelection.FirstOrDefault();

        // do something with item

        // clear currently selected item to allow the same item to be selected again when user
        // navigates back to the page.
        ((CollectionView)sender).SelectedItem = null;
    }
}

Well, the above code causes the SelectionChanged event to fire again (since SelectedItem is changed programmatically) and the event handler to be called twice. And while the humble programmer thinks he/she is on the safe side since e.CurrentSelection is checked for null the ugly truth is that he/she isn't because for some reason known only by the ancient gods, e.CurrentSelection is NOT null the second time and the code breaks with a NullPointerException.

So, if one needs to set the selected item to null then one must double check for null, for example:

private void MyCollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        MyObject item = (MyObject)e.CurrentSelection.FirstOrDefault();

        // double check for null because this handler will be called twice (the second time
        // when SelectedItem is set to null BELOW) in which case e.CurrentSelection is NOT null
        if (item != null)
        {
            // do something useful with item
            ((CollectionView)sender).SelectedItem = null;
        }
    }
}

And that's all there is to it, really. Historically speaking, this exact same kind-of-control-behavior dates back to Visual Basic 6. Oh, well...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants