xamluwpuwp-xamlxboxxbox-one

How to navigate items between several GridViews in a ListView using Xbox controller?


I'm running uwp on xbox, but have some problems on handling the navigation using Dpad or Left stick.

My situation is like this: A ListView, which contains many GridViews. Each GridView is one row defined using xaml code. Just like the picture below. enter image description here

When press key Down/Up, the nearest Item will be focused. For example, if the current focus is on Item1 of GridView1, then Atem1 in GridView2 is focused.

If GridView2 has scrolled to Atem11, Atem12, Atem13, Atem14. And Focus will be transported from Item1 of GridView1 to Atem11 in GridView2. enter image description here

So, how to handle this?


Solution

  • On Xbox One the focus is moved by using an XY navigation system, Mouse mode is enabled by default for UWP apps running on Xbox One. To disable mouse mode and enable XY focus navigation, set Application.RequiresPointerMode=WhenRequested.

    Please check the XY focus navigation and interaction.

    There are three common reasons why XY navigation might not work the way you expect:

    1. The IsTabStop or Visibility property is set wrong.

    2. The control getting focus is actually bigger than you think—XY navigation looks at the total size of the control (ActualWidth and ActualHeight), not just the portion of the control that renders something interesting.

    3. One focusable control is on top of another—XY navigation doesn't support controls that are overlapped.

    If XY navigation is still not working the way you expect after fixing these issues, you can manually point to the element that you want to get focus using the method described in Overriding the default navigation.

    [Updated on 2019/5/23]

    I can't use XY focus, because all the GridViews(One row enabled) are generated dynamically. So XY focus can't handle from one item in GridView1 to another item in GridView2.

    Suppose the focus is on item 1 in GridView1, press down button, the focus goes to item 1 in GridView2. By default, when pressing down button, the focus goes to item 2 in GridVew1.

    With your specific requirement, you could try to monitor the keydown event and check if the gamepad down key is pressed in the event handler. See Nick Kramer [MSFT]'s reply on this case.

    There's two things going on here. First, you'll never get a XAML KeyDown with e.Key == GamepadA/B/left/right/up/down -- they are all translated into their nearest keyboard equivalent. Instead, you can use the e.OriginalKey property to get the gamepad key before it's been translated into the keyboard equivalent.

    After that, you need to check if current focused control is GridView1. You could use FocusManager.GetFocusedElement method. If the current focused control is GridView1, then you could use FocusManager.TryFocusAsync method to make GridView2 focused and set SelectedIndex or SelectedItem to make specific item selected.