Custom XAML controls are a breeze. But, honestly, if you aren’t familiar with building them, there’s a learning curve. Let’s break this barrier and build a custom user control together.
I’ll build a control that works like a standard oven dial. The application uses of such a control are many. The implementation is a little sticky, but I can do it in about 10 minutes. That should raise your confidence a little. Plus, it will demonstrate the flexibility and power of the XAML framework for building complex controls with simple implementation.
Rotate Transform
How do we turn the dial? In XAML, if you want to move something, if you want to rotate something, if you want to skew something, or if you want to scale something – your are likely a fool (a little harsh, sorry) if you don’t use the native transforms to accomplish it.
Natively in the XAML framework are the RotateTransform (turn), ScaleTransform (resize), SkewTransform (twist), and TranslateTransform (move). In this project, we use the RotateTransform. The syntax for all the transforms is pretty simplistic, here’s a sample for using Rotate Transform:
Cartesian Rotation
How do we know how much to move the dial when the user moves their finger?
Wiki: The modern Cartesian coordinate system in two dimensions (also called a rectangular coordinate system) is defined by an ordered pair of perpendicular lines (axes), a single unit of length for both axes, and an orientation for each axis. (Early systems allowed "oblique" axes, that is, axes that did not meet at right angles.) The lines are commonly referred to as the x and y-axes where the x-axis is taken to be horizontal and the y-axis is taken to be vertical. The point where the axes meet is taken as the origin for both, thus turning each axis into a number line. For a given point P, a line is drawn through P perpendicular to the x-axis to meet it at X and second line is drawn through Pperpendicular to the y-axis to meet it at Y. The coordinates of P are then X and Y interpreted as numbers x and y on the corresponding number lines. The coordinates are written as an ordered pair (x, y).
The point where the axes meet is the common origin of the two number lines and is simply called the origin. It is often labeled O and if so then the axes are called Ox and Oy. A plane with x and y-axes defined is often referred to as the Cartesian plane or xy plane. The value of xis called the x-coordinate or abscissa and the value of y is called the y-coordinate or ordinate.
The choices of letters come from the original convention, which is to use the latter part of the alphabet to indicate unknown values. The first part of the alphabet was used to designate known values. In the Cartesian plane, reference is sometimes made to a unit circle or a unit hyperbola.
Rotation Formula
How do we Here’s what we need to do. As the user moves their finder around the dial we have the X, Y coordinates of their “pointer” position. Using the GetAngle() method (below) we can pass the position as well as the boundary and it will return the degrees of rotation.
Get the code here
Manipulation Delta
How do we capture the user’s movement? We use the ManipulationDelta. This method lets us take advantage of getting the user’s pointer position when it moves as well as the inertia even when they remove their finger form the device. (note: mouse works fine).
MSDN: This event is a routed event. An element must have a ManipulationMode other than None to be a manipulation event source. If the event is permitted to bubble up to parent elements because it goes unhandled, then it is possible to handle the event on parent elements even if ManipulationMode is None on that element.
Although this event is a routed event, the ManipulationMode property is not a routed property and it applies only to the specific UIElement on which it is set. For more info on the routed event concept, see Events and routed events overview.
For touch actions and also for interaction-specific or manipulation events that are consequences of a touch action, an element must be hit-test visible in order to be the event source and fire the event that is associated with the action.UIElement.Visibility must be Visible. Other properties of derived types also affect hit-test visibility. For more info, see Hit testing and input events.
Okay, let’s just built it together!
In the video above, we get it done. Hopefully, you are inspired to build something amazing, too. If you do – be sure and show it to me! Until then, best of luck!