locked
How to Scroll a Windows RT GridView Automatically to the Correct Item when the Page First Loads

    Question

  • I have a Windows 8 store app and a GridView with 30 different items. I set the GridView's SelectedItem using a view model. I would expect to see the GridView scroll to the selected item just like a FlipView does, but it does not. In the page's code behind I tried using

    MyGridView.ScrollIntoView(MyGridView.SelectedItem);

    but this only works on the SelectedItemChanged event--not on the page's initial load.  I tried

    Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => MyGridView.ScrollIntoView(MyGridView.SelectedItem));

    No luck here either. How then does one force a GridView to scroll to the proper item when the page first loads?


    • Edited by IMOsiris Friday, October 24, 2014 12:48 PM Typo
    Friday, October 24, 2014 12:43 PM

All replies

  • When are you calling ScrollIntoView?

    You will need to call it after everything is loaded and laid out.

    Friday, October 24, 2014 2:53 PM
    Owner
  • Ok, when is that?
    Friday, October 24, 2014 3:34 PM
  • Hi IMOsiris,

    I'm using the following code in the Loaded event of the page. The GridView is scrolled to the selected item properly. Note that you need to have the exact item from the data source collection of the GridView. I obtain the item by quering the data source:

    // MyViewModel is a type of your item.
    // MyViewModel must have an ID property serving as a primary key.
    // myCollection is the data source collection for your GridView.
    // selectedId is an ID of a selected item you want to scroll to.
    
    // Grab the selected item from the collection.
    MyViewModel selectedItem = myCollection.Where(it => it.ID == selectedId).FirstOrDefault();
    
    if (selectedItem != null)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => 
        { 
            MyGridView.UpdateLayout();
            MyGridView.ScrollIntoView(selectedItem);
        });
    }
    Leszek

    My Apps


    • Edited by ata6502 Friday, October 24, 2014 5:14 PM
    Friday, October 24, 2014 5:13 PM
  • The problem with the code above is that the normal candidates for "myCollection" are still null when this method gets called. I tried the following

    this.Loaded += Page_Loaded;

    private async void Page_Loaded(object sender, RoutedEventArgs e)
            {
                MyViewModel selectedItem = (MyViewSource.Source as IEnumerable<MyViewModel>).
                    Where(x => x.ItemDate == DateTime.Now.ToString("D")).FirstOrDefault();

                if (selectedItem != null)
                {
                    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        MyGridView.UpdateLayout();
                        MyGridView.ScrollIntoView(selectedItem);
                    });
                }
            }

    But MyViewSource.Source is still null when Page_Loaded gets call. I tried my MyGridView.SelectedItem, but that too is still null when Page_Loaded is called. I also tried MyGridView with a direct connection to the view model (i.e., not using MyViewSource), but that did not help. I need to get the selected item after everything is loaded. However, the approaches I've tried all yield a null selected item because they occur before MyGridView is hydrated. Any other ideas?

    Friday, October 24, 2014 9:29 PM
  • How are you initializing your data and when does that occur?

    We don't know your code so we can't tell you what it is doing without your help.

    Friday, October 24, 2014 11:14 PM
    Owner
  • Here is more of my code.

    public sealed partial class ThisPage : VisualStateAwarePage
        {
            private double _scrollViewerOffsetProportion;
            private bool _isPageLoading = true;
            private ScrollViewer _gridViewScrollViewer;

            public StaffMemberCalendarPage()
            {
                this.InitializeComponent();
                this.SizeChanged += Page_SizeChanged;
                this.Loaded += Page_Loaded;
            }       

            private async void Page_Loaded(object sender, RoutedEventArgs e)
            {
                ThisPageViewModel selectedItem = MyGridView.SelectedItem as MyItemViewModel;

                if (selectedItem != null)
                {
                    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        MyGridView.UpdateLayout();
                        MyGridView.ScrollIntoView(selectedItem);
                    });
                }
            }
        }

    This code should cause the GridView to scroll to the selected item, but it doesn't. Any thoughts, or do you need more code from me?

    Saturday, October 25, 2014 1:05 AM
  • I just discovered that MyGridView.ScrollIntoView(selectedItem) works when invoked from the GridView.LayoutUpdated handler. The problem, however, is that while the GridView scrolls to the chosen item horizontal scrolling has become disabled. So if I have 30 items and I correctly see the GridView scrolled to the 22nd item, I cannot then manually scroll to, let's say, the first item. Has anyone experienced this problem and found a solution???
    Monday, October 27, 2014 10:35 PM
  • Can you share a minimal repro sample on your OneDrive? Please include exact repro steps and a clear description of how the expected behaviour differs from the actual behaviour.

    It's very difficult for us to say why your app isn't working when we don't know what it is doing.

    --Rob

    Monday, October 27, 2014 11:49 PM
    Owner