user15900757
user15900757

Reputation:

how to clear collectionview selection in xamarin

On Page#1, i have a collectionview with text/string items list. If you tap a a item, it will get the current tapped text/string and send to Page#2. sound simple

issue I am having: if you tap on item#1, then it will send item#1 to page2, this part working fine. But on page#2, if you hit back button, and tap on item#1 again.. than nothing happens, it doesnt go to page#2

Fix: i think i need to somehow clear tap selection, and than send the item to page#2. but im not sure how to do this

On Page#1, i have a simple collectionview. Collection view contains text/string list

        <CollectionView ItemsSource="{Binding MyListItem}"
                        SelectionMode="Single"
                        SelectionChanged="CollectionView_SelectionChanged">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <ContentView>
                        <!-- Body -->
                        <Grid Padding="0">
                            <Frame CornerRadius="3" BorderColor="#f2f4f5" HasShadow="True">
                                <StackLayout Orientation="Horizontal">
                                    <Image Source="icon_about"
                                               WidthRequest="25"  />
                                    <StackLayout VerticalOptions="Center">
                                        <Label VerticalOptions="Center"
                                                    FontSize="16" 
                                                    Text="{Binding .}" />
                                    </StackLayout>
                                </StackLayout>
                            </Frame>

back end code to handle selection is:

    private async void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var previous = e.PreviousSelection.FirstOrDefault();
        var current = e.CurrentSelection.FirstOrDefault();

        var route = $"{ nameof(Page2) }?URLCardType={current}";
        await Shell.Current.GoToAsync(route);
        
        //clear selection 
        ((CollectionView)sender).SelectedItem = null;
    }

Update ((CollectionView)sender).SelectedItem = null; fixed the issue of clearing selected item but CollectionView_SelectionChanged method is get run twice on single tap. why? this is all the code i have

Upvotes: 3

Views: 3842

Answers (3)

dpant
dpant

Reputation: 2044

This is an old question but since there is no accepted answer and there is an update:

((CollectionView)sender).SelectedItem = null; fixed the issue of clearing selected item but CollectionView_SelectionChanged method is get run twice on single tap. why? this is all the code i have

looking for one I've decided to explain why the following code has a certain side-effect that, historically speaking, dates back to Visual Basic 6:

private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        var current = e.CurrentSelection.FirstOrDefault();

        // do something useful with current
        
        //clear selection 
        ((CollectionView)sender).SelectedItem = null;
    }
}

The above code resembles the OP's code but also checks e.CurrentSelection for null, which is a nice and safe thing to do.

Nevertheless, it also causes the SelectionChanged event to fire again (since SelectedItem is changed programmatically) and the same 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 CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        var current = e.CurrentSelection.FirstOrDefault();

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

Hope this answers both the original question and the updated one and helps people clear the CollectionView's SelectedItem in a (somewhat) safe manner.

Upvotes: 1

Bayron Perdomo
Bayron Perdomo

Reputation: 11

Here is a simple solution that worked for me. Setting to null did not do the trick, it was causing all kinds of weird stuff.

  private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var itemselected = e.CurrentSelection[0] as ProductsItem;
       if (itemselected != null)
        Shell.Current.GoToAsync(nameof(SelectedProductPage));

       //Setting the selected item to an emptyviewproperty after navigation
        CollectionList.SelectedItem = SelectableItemsView.EmptyViewProperty;
    }

Upvotes: 0

user15900757
user15900757

Reputation:

@jason thanks, this worked for me. i just had to check if selection item is null than do nothing

  private async void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
         var MyCollectionView = sender as CollectionView;  
            if (MyCollectionView.SelectedItem == null)
                return;

        var previous = e.PreviousSelection.FirstOrDefault();
        var current = e.CurrentSelection.FirstOrDefault();

        var route = $"{ nameof(Page2) }?URLCardType={current}";
        await Shell.Current.GoToAsync(route);
        
        //clear selection 
       MyCollectionView.SelectedItem = null;
    }

Upvotes: 2

Related Questions