Reputation:
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
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
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
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