locked
CollectionViewSource MoveCurrentToPosition doesnt seem to work

    Question

  • I've added the following Xaml to a the MainPage.xaml of a Blank Universal App.

    <ListView x:Name="bindableList" ></ListView>
    <ListView x:Name="bindableList2" HorizontalAlignment="Right"></ListView>

    And this is what my OnNavigated looks like for that MainPage.xaml.cs

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        var list = new ObservableCollection<string>();
        var collectionSource = new CollectionViewSource { Source = list, IsSourceGrouped = false };
                
        bindableList.SetBinding(ItemsControl.ItemsSourceProperty, new Binding { Source = collectionSource });
        bindableList2.SetBinding(ItemsControl.ItemsSourceProperty, new Binding { Source = collectionSource });
                
        for (int i = 0; i < 1000; i++)
        {
            list.Add(i.ToString());
        }
                
    
        var result = collectionSource.View.MoveCurrentToPosition(500);
    }

    When you run it, you can see that neither of the ListViews will be scrolled to show element 500 and when making selections in the ListView on the right, there is no scroll synchronization with the ListView on the left, however selections on the left will cause the ListView on the right to scroll and show the selection status.

    If I add  await Task.Delay(1000) prior to the MoveCurrentToPosition it will re-position the ListViews successfully. Why is this behavior so inconsistent? and if this isn't how I'm supposed to synchronize scroll/selection between two ListViews what am I supposed to use?


    Friday, January 09, 2015 12:28 AM

All replies

  • Hi Jeff,

    Thanks for your code and explanation, I can reproduce the issue.

    If I add Task.Delay(1000) before the MoveToCurrentPosition() method, the first listview 500th item can be selected. Actually Task.Delay(10) is also workable, I believe there should be some UI un-responsible behavior here.

    I will further look into the code and also consult our seniors to give you some updates.

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Friday, January 09, 2015 6:04 AM
    Moderator
  • Personally I would not suggest you to use Task.Delay() because it looks not reasonable.

    I would say we register a ListView loaded event first and when the UI is finished rendered (it might take nearly 10ms so we use Task.Delay(1) does not work in the app), we scroll the item to the correct position.

    Below is some reasonable code I can provided instead of using Task.Delay:

            bindableList.Loaded += bindableList_Loaded;
    
            void bindableList_Loaded(object sender, RoutedEventArgs e)
            {
                bindableList.ScrollIntoView(list[500]);
                collectionSource.View.MoveCurrentToPosition(500);
            }

    Besides, I have some finding on this:

    #1, Without Task.Delay(), MoveCurrentToPosition() can only move to the visible items in the ListView, for instance we set the number as 17, the 17th item can be selected.

    #2, If we disable the UI-virtualization, the collectionSource.View.MoveCurrentToPosition() can select the correct item but cannot move to the suitable place.

    I think there should be some mechanism in MoveCurrentToPosition() method but we cannot look into it, the only documentation is on MSDN without many description. I will consult seniors to see if we can provide furthermore explanations.

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, January 09, 2015 8:11 AM
    Moderator
  • The problem with putting the delay in, is that I don't want it to display the top of the list and then scroll to my target, i want it to just display my target. The flash and jitter in the UI that is caused by letting it render once before the scroll is completely unacceptable for what is supposed to be a fast fluid app.
    • Edited by JeffGreene Friday, January 09, 2015 4:31 PM typo
    Friday, January 09, 2015 4:00 PM
  • This really seems like a bug, have you been able to talk to anyone about better ways of working around it?
    Wednesday, January 21, 2015 8:47 PM