.NET Gaming Documentation

Introduction

Welcome to the UI tutorial for the .NET Gaming platform. In this guide you’ll learn how to create responsive game menus, HUDs, and interactive dialogs using XAML and C#.

XAML UI Basics

Creating a Simple Menu

Define your UI layout in XAML. The GamePage serves as the root container.

<GamePage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBlock Text="Main Menu" FontSize="48" Margin="0,0,0,30"/>
        <Button Content="Start Game" Width="200" Margin="0,5"/>
        <Button Content="Options" Width="200" Margin="0,5"/>
        <Button Content="Exit" Width="200" Margin="0,5"/>
    </StackPanel>
</GamePage>

Binding Data

Use INotifyPropertyChanged in your view model to update UI elements dynamically.

public class MenuViewModel : INotifyPropertyChanged
{
    private string _title = "Main Menu";
    public string Title
    {
        get => _title;
        set { _title = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string name = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

Input Handling

Keyboard, mouse, and gamepad input are routed through the GameInput service.

public sealed class InputHandler : IGameComponent
{
    public void Update(GameTime time)
    {
        if (GameInput.IsKeyPressed(Keys.Enter))
        {
            // Start the game
        }

        if (GameInput.Gamepad.Buttons.Start == ButtonState.Pressed)
        {
            // Open options
        }
    }
}

Custom Controls

Create reusable controls by extending Control and defining a default style.

public class AnimatedButton : Button
{
    public AnimatedButton()
    {
        this.DefaultStyleKey = typeof(AnimatedButton);
    }

    protected override void OnPointerEntered(PointerRoutedEventArgs e)
    {
        VisualStateManager.GoToState(this, "PointerOver", true);
        base.OnPointerEntered(e);
    }
}

Define the visual states in Generic.xaml:

<Style TargetType="local:AnimatedButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:AnimatedButton">
                <Grid>
                    <Border x:Name="Border"
                            Background="{TemplateBinding Background}"
                            CornerRadius="6"/>
                    <ContentPresenter HorizontalAlignment="Center"
                                      VerticalAlignment="Center"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal"/>
                        <VisualState x:Name="PointerOver">
                            <Storyboard>
                                <ColorAnimation To="#FF4CAF50"
                                                 Duration="0:0:0.2"
                                                 Storyboard.TargetName="Border"
                                                 Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"/>
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Sample Project

Download the complete UI sample from the GitHub repository or clone it:

git clone https://github.com/dotnet/gaming-samples.git
cd gaming-samples/UI
dotnet build
dotnet run

Resources