locked
Scrolling a GridView so the selected item is visible

    Question

  • I don't see any XAML syntax for declaring that a GridView should keep the selected item visible. In lieu of that, I have tried to use the ScrollIntoView method in the code-behind, but to no avail.

    Here is my GridView XAML:

      <GridView x:Name="HorizontalViewer"
                Grid.Row="1"
                Grid.Column="1"
                VerticalAlignment="Top"
                Padding="0,0,40,50"
                ItemsSource="{Binding AllStudents}"
                ItemTemplate="{StaticResource FullItemTemplate}"
                SelectionMode="Single"
                ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                IsItemClickEnabled="True"
                SelectedItem="{Binding SelectedStudent}"
                ItemClick="StudentClicked"
                Loaded="WhenListViewBaseLoaded"
                Visibility="Visible">
      </GridView>

    And here is the code-behind event handler I added:

        Private Sub WhenListViewBaseLoaded(sender As Object, e As RoutedEventArgs)
            Dim itemsControl = DirectCast(sender, ListViewBase)

            If itemsControl.SelectedItem IsNot Nothing Then
                itemsControl.ScrollIntoView(itemsControl.SelectedItem)
            End If

        End Sub

    Please note that I am using the GridView in click mode to navigate to another page. But I like the visual feedback of the Select-One gridview usage. So when an item is clicked it is also set as selected. This is so that when I return to this overview page, I have the visual feedback of what had been selected. The selection visual works fine, but the ScrollIntoView method, though called appropriately, has no effect. All looks fine in the debugger, just nothing happens scroll-wise. Note also that I am not using any semantic zoom stuff. This is just a plain GridView.

    Note also that there is a rather squirrelly note in the ListVioewBase.ScrollIntoView method documentation that says "you might need to call UpdateLayout prior to calling ScrollIntoView for the specified item to scroll into the viewport." I played with that (calling UpdateLayout before, after, and before-and-after) but that had no effect.

    I am using Visual Studio Express 2013 for Windows (Version 12.0.30501.00 Update 2) on Windows 8.1

    The bindings are very simple. AllStudents points to a simple ObservableCollection(of Student), where Student is a very simple class (student data). CurrentStudent points at the currently selected Student object. The data set only consists of 8-10 students, and at this point it is all just read-only.

    From the notes I have seen on the web regarding similar difficulties I am suspicious of some sort of subtle type mismatch. But I am not seeing it. Hopefully it is obvious and dumb on my part!

    Thursday, August 21, 2014 1:14 AM

All replies

  • Hi TomEire,

    The code you provide looks good, could you share us a reproducible demo for test, for instance share on the OneDrive.

    I saw you have this line: The selection visual works fine, but the ScrollIntoView method, though called appropriately, has no effect. I assume that your selection action and ScrollIntoView method runs at the same time so that the system does not know which one to scroll.

    Let's say we could try to finish the select action and then scrollIntoView, try the code and let's see the result:

            TimeSpan period = TimeSpan.FromMilliseconds(10);
            Windows.System.Threading.ThreadPoolTimer.CreateTimer(async (source) =>
                {
                    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        ScrollIntoView()...
                    });
                }
                , period);
    

    --James

    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, August 21, 2014 12:07 PM
    Moderator
  • Hello James,

    Thank you for taking a look at my issue. I will try to boil this down into a small test case shortly. While the current state of this app is very simple, it still needs to be pared down for such a purpose.

    To the point that you raised, what I meant by that statement is that when I watched the LOADED event handler in the debugger itemsControl.SelectedItem had the correct value and the call to itemsControl.ScrollIntoView was made accordingly (alas to no effect). I would have assumed that the LOADED event would have been fired after the select action had been completed.

    That was - in fact - the only reason I had added this event handler. Originally without that event handler I could see (with the debugger) that the ScrollIntoView call (when it was just inline) occasionally got made when there were yet to be any items in the GridView (presumably because the itemssource binding is declared in XAML, not the code-behind).

    It wouldn't be a surprise if it all would work properly if I did all the work in the code-behind (setting the items source, setting the selected item, scrolling to the selected item, etc.) But that would defeat the purpose of the simplicity of the XAML binding. A KeepSelectionVisible declaration would be optimal.

    Thursday, August 21, 2014 4:07 PM