The Surface Dial is the first wheel device in a new input device class. I got my hand on one as soon as it came to market in China.

I have a UWP App named "Image Portray", as a drawing app that can make use of the Surface Dial. One of it's useful application to undo / redo the ink by turning the Surface Dial. You can download it from Windows Store these days to see the changes.

So, let's begin with some basics of the Surface Dial. If you haven't used one yet, it is basically a bluetooth device that will pair with any Windows 10 desktop machine, Windows will handle default menu items, and you can modify custom tools in Windows Settings.

But for particular UWP Apps, developers are allowed to add app sepecific tools to the Surface Dial menu, or hiding the system default menu is also supportted. Some UWP controls by default has support for Surface Dial, like the InkToolbar:

(Picture from https://docs.microsoft.com/en-us/windows/uwp/input-and-devices/windows-wheel-interactions)

To add a custom tool, we need to define a RadialController object.

private RadialController dialController;

Then, initialize it

dialController = RadialController.CreateForCurrentView();

Set a few basic settings

dialController.UseAutomaticHapticFeedback = true;
dialController.RotationResolutionInDegrees = 1;

The UseAutomaticHapticFeedback means, when user operates with the Dial, it will vibrate to feedback the user.

The RotationResolutionInDegrees means, how far the user turns the Dial will trigger our custom events. I set the value to 1 just to make the Dial very very sensitive to any rotation.

We also need a event handler to listen to the rotation:

dialController.RotationChanged += DialController_RotationChanged;

Then, we will add the undo / redo tool menu. 

private RadialControllerMenuItem dialToolUndo;
...
// Undo Tool
diaoToolUndo = RadialControllerMenuItem.CreateFromFontGlyph("Undo / Redo", "\xE10E",
"Segoe MDL2 Assets");
dialController.Menu.Items.Add(diaoToolUndo);
dialToolUndo.Invoked += DiaoToolUndo_Invoked;

I strongly recommend to use Segoe MDL2 Assets for the icons, because the default icon Enum for the Dial is very limited.

In the event handler, we can display a message for the user to let them know current selection is the undo / redo tool. In my app, it is:

private void DialToolUndo_Invoked(RadialControllerMenuItem sender, object args)
{
    TxtMessage.Text = "Undo / Redo Selected";
    BorderFadeInStoryboard.Begin();
}

Then, we can write logic in the previous event handler DialController_RotationChanged:

private void DialController_RotationChanged(RadialController sender, RadialControllerRotationChangedEventArgs args)
{
    var selectedTool = dialController.Menu.GetSelectedMenuItem();
    if (selectedTool == dialToolUndo)
    {
        if (args.RotationDeltaInDegrees < 0)
        {
            ViewModel.InkOperator.UndoLastStorke();
        }
        else
        {
            ViewModel.InkOperator.RedoLastStorke();
        }
    }
}

The args.RotationDeltaInDegrees < 0 means, user is rotating the Dial to left, we will perform an Undo operation for that. If the value is > 0, user is rotating the Dial to right, then perform a Redo operation.

For the logic in UndoLastStorke() and RedoLastStorke(), please check my previous blog post:

Windows 10 UWP: Undo / Redo on InkCanvas