AndreiMisiukevich / CardView

CardsView | CarouselView | CoverflowView | CubeView for Xamarin.Forms
MIT License
710 stars 114 forks source link

Carousel View sets selected index to 0 on init even though selected item is not index 0 #372

Closed Jcook65 closed 3 years ago

Jcook65 commented 3 years ago

I am in a situation where I am trying to load a page with the CarouselView at the position that the user was in when they last left the page (or closed the application). I am doing this by binding the SelectedItem to the last selected item in the carousel's bound list. What is happening though is that the CarouselView always starts at index 0 regardless of what the SelectedItem is bound to and then will change the SelectedItem to match the index.

When I put a break point in the property changed event, to observe what is happening, I am noticing that the carousel starts with the correct selected item but with an index of -1, since I am loading a list and the selected item gets bound before the list is done loading. I guess since the Item isnt found in the empty list it sets the index to -1. I am assuming that after the page is done initializing it sets that -1 to 0? and then that updates the SelectedItem as a consequence. I have tried to set the binding of SelectedItem after the ItemSource property changed but this doesnt work either.

I might be wrong in that assessment but I guess my question is: is it possible to drive the carousel from a bound SelectedItem? or do I have to bind to the SelectedIndex to get the kind of behavior I am wanting?

AndreiMisiukevich commented 3 years ago

Hey @Jcook65 try next

1) Set IsAutoNavigatingAnimationEnabled = false 2) Set SelectedItems 3) Set IsAutoNavigatingAnimationEnabled = true

AndreiMisiukevich commented 3 years ago

@Jcook65 did it help?

Jcook65 commented 3 years ago

hey @AndreiMisiukevich, sorry for the delayed response. I actually ended up just converting the selected item to and index and binding to the SelectedIndex instead of the SelectedItem and it works fine now. I haven't had the time to go back and try it the way you suggested here. I must've missed that property on the carousel but it sounds like it would help this situation. Thank you for the swift response!

InquisitorJax commented 3 years ago

@AndreiMisiukevich methinks this is still an issue. We're binding to SelectedIndex to drive the pre-selected item as @Jcook65 mentions. It seems the SetNewIndex method that gets called from SetItemSource in CardsView ignores the current value of SelectedIndex. Unfortunately I can only repro the binding firing the same value back to the ViewModel property, but in our main project, if the SelectedIndex was 3, the SetNewIndex is resetting this back to zero - and it doesn't happen every time, so perhaps there's a timing / threading issue there? Stack trace: image

AndreiMisiukevich commented 3 years ago

@InquisitorJax I guess it happens because SelectedItem/SelectedIndex binding is performed before ItemsSource binding.

AndreiMisiukevich commented 3 years ago

hmm, or maybe even vice versa (because index binding performed earlier)

AndreiMisiukevich commented 3 years ago

@InquisitorJax try to reorder bindings in your xaml.

Or even try to bind SelectedIndex in xaml and ItemsSource in code-behind

AndreiMisiukevich commented 3 years ago

@InquisitorJax I think we should open a new ticket for this problem, cuz this one is related to SelectedItem.

Unfortunately, SelectedItem cannot be used for setting initial value (because it just sets selected index)

var view = bindable.AsCardsView();
view.SelectedIndex = view.ItemsSource?.FindIndex(newValue) ?? -1;

And if ItemsSource is not set before the selected item, then it will be reset to null.

That's why SelectedIndex should be used for such cases.

AndreiMisiukevich commented 3 years ago

@InquisitorJax maybe you can create a new issue and attach a sample? Or maybe you have a chance to debug the lib on your main project to see why it resets to 0?

AndreiMisiukevich commented 3 years ago

Also, it can happen if you use "null" items or items with the same value (e.g. items are integers or strings with the same value)

AndreiMisiukevich commented 3 years ago

Also, it can happen if you set SelectedIndex (e.g. to 3), bind ItemsSource to ObservableCollection (empty). And start to add elements one by one after that.

InquisitorJax commented 3 years ago

I'll open a new ticket, thanks Andrei. So we bind ItemSource to generic List, and Selected Index. Attaching the project ot debug is a good idea - I'll try that, and report what I find.