Input and focus¶
Controller events¶
The Xbox runtime adds controller events to every UIElement (System.Windows, namespace System.Windows.Input):
| Event | Arguments |
|---|---|
GamePadButtonDown, GamePadButtonUp |
GamePadButtonEventArgs.Button: A, B, X, Y, the D-pad directions, the shoulders, Start, Back, and the stick clicks. |
GamePadThumbStickMoved |
Side (left or right), XPosition and YPosition. Each runs from -1 to 1; Y is positive up. |
GamePadTriggerMoved |
Side, Position from 0 (released) to 1 (fully pulled). |
MediaCommand |
MediaCommandEventArgs.MediaCommand: play, pause, fast forward and the rest, from a media remote. |
They are routed events: raised on the element with focus, then bubbling up through its parents, like KeyDown. Set e.Handled = true to stop one. The guide button never reaches apps.
GamePadButtonDown += delegate(object sender, GamePadButtonEventArgs e)
{
if (e.Button == GamePadButton.Y)
{
ShowDetails();
e.Handled = true;
}
};
GamePadButtonDownEvent and GamePadButtonUpEvent are also exposed as RoutedEvents, for AddHandler(..., handledEventsToo: true). The stick and trigger events aren't.
samples\ui\GamepadInput shows every event live.
Focus¶
With nothing focused, no element gets controller input. A UserControl isn't focusable by default, so either set IsTabStop = true on it and call Focus(), or focus a control, in Loaded or OnNavigatedTo:
Loaded += delegate { FirstTile.Focus(); };
After a navigation, focus from Dispatcher.BeginInvoke so the page is in the tree first.
What the runtime does on its own¶
- A clicks the focused
Button. Start and the remote's play/pause command do too, and the event is marked handled.Clickarguments are anInputModalityRoutedEventArgs; itsInputModalitysays whether the click came from the controller, voice, a Kinect gesture, a remote, the keyboard or the mouse. - The D-pad doesn't move focus between plain controls. In testing, pressing the D-pad over a
GridofButtons left focus where it was. PivotItemdoes move focus. WithAutoGridNav(on by default), aPivotItemmoves focus through theGridit contains with the D-pad, and thePivotchanges items with the shoulder buttons.ContinuousListpages with the shoulder buttons and D-pad. See Xbox controls.
Moving focus yourself¶
For layouts outside a Pivot, the samples include samples\Common\DirectionalFocus.cs. Turn it on for a panel and the D-pad and left stick move focus to the nearest focusable control in that direction:
<UserControl xmlns:sdk="clr-namespace:XboxSdk.Samples" ...>
<Grid sdk:DirectionalFocus.IsEnabled="True">
...buttons...
</Grid>
</UserControl>
It considers every visible, enabled control with IsTabStop set among the panel's descendants. It picks the closest one in the pressed direction, preferring ones lined up with the current control. Disabled controls and IsTabStop="False" ones are skipped. Add the file to your project with <Compile Include="...\Common\DirectionalFocus.cs" />. samples\ui\FocusNavigation shows it on a grid with a wide tile, a disabled one and one that isn't a tab stop.
Showing focus¶
TV users only know where they are from the focus visual, so make it obvious: a filled background, a frame, a slight zoom. Every sample's Button template has a FocusStates group with a green fill or frame in Focused.
The Legend¶
Legend (Microsoft.Xbox.Controls) shows what A, B, X and Y do. It reads attached properties from the focused element, or its nearest ancestor that has them:
<Button Content="Watch list"
xbox:Legend.AButtonText="open" xbox:Legend.XButtonText="clear list" />
...
<xbox:Legend HorizontalAlignment="Right" VerticalAlignment="Bottom" />
The attached properties can only be set on a Button, Pivot, ContinuousList, XboxApplicationFrame, Rune or NuiScrollViewer. Setting them on anything else throws. The Legend hides itself while the user is using Kinect gestures.
Media remotes¶
A media remote's buttons arrive as MediaCommand events on the focused element. MediaTransport handles them itself. For your own player, handle UIElement.MediaCommand and switch on e.MediaCommand.
Kinect and speech¶
Kinect gestures drive a hand cursor that arrives as mouse events: hovering a Button focuses it, and holding the hover clicks it. Speech commands (VuiBar, VuiCommand, VuiGrammar) need a Kinect sensor. Neither has been tested; xenia has no Kinect.