{"id":2156,"date":"2015-10-25T03:00:00","date_gmt":"2015-10-25T10:00:00","guid":{"rendered":"https:\/\/www.microsoft.com\/reallifecode\/index.php\/2015\/10\/25\/building-a-radial-menu-control-for-surface-devices\/"},"modified":"2020-03-18T15:36:36","modified_gmt":"2020-03-18T22:36:36","slug":"building-a-radial-menu-control-for-surface-devices","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/ise\/building-a-radial-menu-control-for-surface-devices\/","title":{"rendered":"Building a Radial Menu Control for Surface Devices"},"content":{"rendered":"<p>User interfaces should not stand between user and content &#8211; a known golden rule that can be difficult to implement. For presentation-heavy applications dealing with notes, images, or documents, being as unobtrusive as possible has always been an important mantra. The most popular apps in those fields tend to have user interfaces that collapse or even disappear entirely. One popular solution is a flexible radial control, which the user can drag around on-screen, providing as little or as much interaction as the user wants.<\/p>\n<p>In preparation for the launch of the new Surface Book, the Surface Pro 4 as well as the Surface Hub, we built and open sourced a powerful radial control for XAML\/C# Universal Windows Apps together with the popular PDF Reader and Annotation app <a href=\"http:\/\/www.drawboard.com\/\">Drawboard<\/a>.<\/p>\n<p>This code story describes how we built the control &#8211; and how your app can benefit from the open source code that will be preinstalled on Surface devices. It first explains the features before guiding you through building a small \u201cHello Radial Control\u201d app.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-25-drawboard-gif.gif\" alt=\"Animated GIF of the Radial Menu\" \/><\/p>\n<h2 id=\"requirements-features-benefits\">Requirements, Features, Benefits<\/h2>\n<p>For those uninitiated, Drawboard is a powerful PDF Annotation app that can be currently found on Surface devices. It\u2019s a true game changer for professionals who spend a lot of their time scribbling on large documents &#8211; the typical example being a civil engineer confronted with hundreds of ever-changing building plans. Replacing dozens of gigantic printouts with a Surface and its stylus is a dramatic leap towards mobility. Built in beautiful Melbourne by a small startup, the Drawboard app provides such great value that it is preinstalled on new Surface devices including Surface Hub, Surface Pro and Surface Book.<\/p>\n<p>To provide a good user experience, the app uses as much screen real estate as possible for the actual PDF currently displayed. Interactions, like the selection of various digital markers or pens, happen on a radial menu control, which the user can drag around the screen and position wherever it is convenient. While the experience is great, Drawboard outgrew the control purchased from a third party provider &#8211; it wasn\u2019t as flexible or powerful as needed for future features while also consuming too many resources. In particular, the shortcomings included frequent crashes, suspected memory leaks, lack of flexibility in usage, unavailability of source code, and a restrictive license.<\/p>\n<h5 id=\"lets-build-a-better-control\">Let\u2019s Build a Better Control<\/h5>\n<p>Let\u2019s take a quick look at the feature list, starting with the pieces that make up the control: In the middle, we have a center button, which is surrounded by a variable number of buttons. Each button contains two clickable pieces: A rim on the outside and an inner part. The inner portion contains the primary action, while the outer rim opens up additional options to configure the primary action. Those pience are decorated with icons, labels, and colors for various pointer states.<\/p>\n<p>Beyond a simple button, we have the various ways users can interact with the primary portion. Each button is capable of being a host for a submenu, which can be opened by clicking on the outer rim. The button itself can either be a simple one, behaving just like a normal XAML button &#8211; but it can also be a toggle or radio button, capable of being either selected or unselected.<\/p>\n<p>In addition to those features, we sprinkled in some special features to enable cool scenarios &#8211; most notably around the submenus accessible by clicking on the outer rim of a button. If the user is asked to select from a large number of options (like a font list), you can use a \u201clong list selector\u201d instead. If the user is asked to select a numeric value, you can make use of the \u201cmeter submenu\u201d &#8211; an interactive gauge, allowing the user to move the needle to the right value. If none of those options seem appropriate for selection, you can use the \u201ccustom input\u201d button, which allows the user to enter a value directly into the button.<\/p>\n<p>Around all those features, we also have a small floating control, which enables the radial menu to float around in your application. Getting the floating behavior right is a difficult task and involves a large amount of subjectivity &#8211; for that reason, we split up the radial menu and the floating control into two pieces, allowing you to mix and match. This concept applies to the whole project: We built the control with large amounts of flexibility, breaking pieces into as many small modules as possible. This makes it tremendously easy to tweak settings or to add additional features to the control, should that be required.<\/p>\n<h2 id=\"using-the-control-in-your-application\">Using the Control in Your Application<\/h2>\n<p>To explore the usage of the Radial Menu Control, fork, download or clone the <a href=\"https:\/\/github.com\/catalystcode\/radial-menu\">Git repository<\/a>. If you prefer NuGet, you can install it using the Visual Studio Package Manager:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>PM&gt; Install-Package RadialMenuControl\r\n<\/code><\/pre>\n<\/div>\n<p>To explore the full flexibility of the control, we walk through building a simple \u201cHello Radial Control\u201d app. Open up <code class=\"highlighter-rouge\">RadialMenu.sln<\/code> in Visual Studio 2015, where you will find two projects: <code class=\"highlighter-rouge\">RadialMenuControl<\/code> (the actual control) and <code class=\"highlighter-rouge\">RadialMenuDemo<\/code> (which you can ignore for now).<\/p>\n<p>To get started, add a new \u2018Universal Windows Blank App\u2019 project using XAML and C# to the solution, naming it <code class=\"highlighter-rouge\">HelloRadialMenu<\/code>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-25-drawboard-addproject.png\" alt=\"Add a new project\" \/><\/p>\n<p>Then, add the <code class=\"highlighter-rouge\">RadialMenuControl<\/code> as a reference to your project.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-25-drawboard-reference.png\" alt=\"Add a the reference\" \/><\/p>\n<p>At the core, this control comes with three XAML user controls: The first one is a <code class=\"highlighter-rouge\">Floating<\/code> control, enabling a child element to float on top of all other elements, which allows the user to move said element around on the screen. The second one is the <code class=\"highlighter-rouge\">RadialMenu<\/code> itself, which is able to house a number of <code class=\"highlighter-rouge\">RadialMenuButtons<\/code>. Should a button contain a submenu, the button then houses a <code class=\"highlighter-rouge\">RadialMenu<\/code> (or a custom submenu control).<\/p>\n<p>Let\u2019s add a floating control and a simple Radial Menu to our <code class=\"highlighter-rouge\">MainPage.xaml<\/code>. Open up the file and add <code class=\"highlighter-rouge\">xmlns<\/code> references to your XAML page. You need add a reference to two namespaces: <code class=\"highlighter-rouge\">RadialMenuControl.UserControl<\/code> and <code class=\"highlighter-rouge\">RadialMenuControl.Components<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>&lt;Page\r\n    x:Class=\"HelloRadialMenu.MainPage\"\r\n    xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\r\n    xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\r\n    xmlns:local=\"using:HelloRadialMenu\"\r\n    xmlns:d=\"http:\/\/schemas.microsoft.com\/expression\/blend\/2008\"\r\n    xmlns:mc=\"http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006\"\r\n    xmlns:userControl=\"using:RadialMenuControl.UserControl\"\r\n    xmlns:components=\"using:RadialMenuControl.Components\"\r\n    mc:Ignorable=\"d\"&gt;\r\n    &lt;!-- ... --&gt;\r\n&lt;\/Page&gt;\r\n<\/code><\/pre>\n<\/div>\n<p>You might be wondering why we have two namespaces here &#8211; the reason lies in the abstraction of the radial menu button, done to optimize performance and minimize resource usage. When added to the radial menu, the button is just used to generate a radial menu in a certain state.<\/p>\n<p>Next, we\u2019ll add the <code class=\"highlighter-rouge\">Floating<\/code> as well as the <code class=\"highlighter-rouge\">RadialMenu<\/code> control. Add a <code class=\"highlighter-rouge\">Canvas<\/code> to your MainPage\u2019s grid and fill it with a <code class=\"highlighter-rouge\">Floating<\/code> user control. The floating control has two parameters of interest: You can set either <code class=\"highlighter-rouge\">IsBoundByScreen<\/code> or <code class=\"highlighter-rouge\">IsBoundByParent<\/code> to <code class=\"highlighter-rouge\">true<\/code> to configure how far the user is allowed to drag the control. The floating control can have only one child, which is ideally the often abused <code class=\"highlighter-rouge\">Border<\/code> element, which we filled with another <code class=\"highlighter-rouge\">Grid<\/code> to ensure that XAML renders inside the radial control correctly.<\/p>\n<p>Inside the Grid, add the <code class=\"highlighter-rouge\">RadialMenu<\/code> like outlined below. The <code class=\"highlighter-rouge\">RadialMenu<\/code> has a bunch of options, but to get started, just set the <code class=\"highlighter-rouge\">Diameter<\/code>, the <code class=\"highlighter-rouge\">StartAngle<\/code>, the <code class=\"highlighter-rouge\">CenterButtonIcon<\/code> (which we set to a donut), and the <code class=\"highlighter-rouge\">CenterButtonBorder<\/code>. The diameter describes the total width and height of the radial menu, while the starting angle is the angle at which the first button is drawn. If you leave it unset (or set it to 0), the first button will be drawn at \u201cnorth top\u201d. Also, just to make things less boring, we set the Grid\u2019s background to <code class=\"highlighter-rouge\">GhostWhite<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>&lt;Grid Background=\"GhostWhite\"&gt;\r\n    &lt;Canvas&gt;\r\n        &lt;userControl:Floating IsBoundByScreen=\"True\"&gt;\r\n            &lt;Border&gt;\r\n                &lt;Grid&gt;\r\n                    &lt;userControl:RadialMenu Diameter=\"300\" StartAngle=\"-22.5\" CenterButtonIcon=\"\ud83c\udf69\" CenterButtonBorder=\"Black\"&gt;\r\n                    &lt;\/userControl:RadialMenu&gt;\r\n                &lt;\/Grid&gt;\r\n            &lt;\/Border&gt;\r\n        &lt;\/userControl:Floating&gt;\r\n    &lt;\/Canvas&gt;\r\n&lt;\/Grid&gt;\r\n<\/code><\/pre>\n<\/div>\n<p>The control itself is fairly boring without any buttons, so let\u2019s jump right in and add some buttons. Buttons can be added either in code-behind or in XAML, but in both cases they need to be added to the controls <code class=\"highlighter-rouge\">Buttons<\/code> property. For a basic button, simply set the <code class=\"highlighter-rouge\">Label<\/code> and the <code class=\"highlighter-rouge\">Icon<\/code> property. For best performance, we recommend that you use icon fonts &#8211; you can either copy our use of emojis (which don\u2019t require that you set a font), or use a specialized icon font like Font Awesome or Segoe UI Symbol by setting the <code class=\"highlighter-rouge\">IconFontFamily<\/code> option. If you need to use an image, simply set the <code class=\"highlighter-rouge\">IconImage<\/code> property to an <code class=\"highlighter-rouge\">ImageSource<\/code> &#8211; if set, it will automatically supersede a text-based icon.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>&lt;Grid Background=\"GhostWhite\"&gt;\r\n    &lt;Canvas&gt;\r\n        &lt;userControl:Floating IsBoundByScreen=\"True\"&gt;\r\n            &lt;Border&gt;\r\n                &lt;Grid&gt;\r\n                    &lt;userControl:RadialMenu Diameter=\"300\" StartAngle=\"-22.5\" CenterButtonIcon=\"\ud83c\udf69\" CenterButtonBorder=\"Black\"&gt;\r\n                        &lt;userControl:RadialMenu.Buttons&gt;\r\n                            &lt;components:RadialMenuButton Label=\"Melbourne\" Icon=\"\ud83c\udf0f\" \/&gt;\r\n                            &lt;components:RadialMenuButton Label=\"Sun\" Icon=\"\ud83c\udf1e\" \/&gt;\r\n                            &lt;components:RadialMenuButton Label=\"Food\" Icon=\"\ud83c\udf71\" \/&gt;\r\n                            &lt;components:RadialMenuButton Label=\"Halloween\" Icon=\"\ud83c\udf83\" \/&gt;\r\n                        &lt;\/userControl:RadialMenu.Buttons&gt;\r\n                    &lt;\/userControl:RadialMenu&gt;\r\n                &lt;\/Grid&gt;\r\n            &lt;\/Border&gt;\r\n        &lt;\/userControl:Floating&gt;\r\n    &lt;\/Canvas&gt;\r\n&lt;\/Grid&gt;\r\n<\/code><\/pre>\n<\/div>\n<p>With those basics set, go ahead and build\/deploy\/run the app by hitting F5. If you\u2019re not seeing the app you\u2019ve just been working on, ensure that your new <code class=\"highlighter-rouge\">HelloRadialMenu<\/code> app is the \u201cStartUp Project\u201d by right-clicking on the project and selecting the \u201cSet as StartUp Project\u201d option.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-25-drawboard-tutorial1.png\" alt=\"Screenshot of the &quot;Hello Radial Menu App&quot;\" \/><\/p>\n<h4 id=\"adding-submenus\">Adding Submenus<\/h4>\n<p>A common use case for radial menus is a toolbox, enabling the user to select a tool. Let\u2019s assume that the <code class=\"highlighter-rouge\">Food<\/code> button should have a submenu, offering the user various food items. To add a simple submenu, simply pass a <code class=\"highlighter-rouge\">RadialMenu<\/code> the a button\u2019s <code class=\"highlighter-rouge\">Submenu<\/code> property.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>&lt;userControl:RadialMenu Diameter=\"300\" StartAngle=\"-22.5\" CenterButtonIcon=\"\ud83c\udf69\" CenterButtonBorder=\"Black\"&gt;\r\n    &lt;userControl:RadialMenu.Buttons&gt;\r\n        &lt;components:RadialMenuButton Label=\"Melbourne\" Icon=\"\ud83c\udf0f\" \/&gt;\r\n        &lt;components:RadialMenuButton Label=\"Sun\" Icon=\"\ud83c\udf1e\" \/&gt;\r\n        &lt;components:RadialMenuButton Label=\"Food\" Icon=\"\ud83c\udf71\"&gt;\r\n            &lt;components:RadialMenuButton.Submenu&gt;\r\n                &lt;userControl:RadialMenu&gt;\r\n                    &lt;userControl:RadialMenu.Buttons&gt;\r\n                        &lt;components:RadialMenuButton Label=\"Fries\" Icon=\"\ud83c\udf5f\" \/&gt;\r\n                        &lt;components:RadialMenuButton Label=\"Eggs\" Icon=\"\ud83c\udf73\" \/&gt;\r\n                        &lt;components:RadialMenuButton Label=\"Ice Cream\" Icon=\"\ud83c\udf68\" \/&gt;\r\n                        &lt;components:RadialMenuButton Label=\"Noodles\" Icon=\"\ud83c\udf5c\" \/&gt;\r\n                        &lt;components:RadialMenuButton Label=\"Burger\" Icon=\"\ud83c\udf54\" \/&gt;\r\n                        &lt;components:RadialMenuButton Label=\"Pizza\" Icon=\"\ud83c\udf55\" \/&gt;\r\n                    &lt;\/userControl:RadialMenu.Buttons&gt;\r\n                &lt;\/userControl:RadialMenu&gt;\r\n            &lt;\/components:RadialMenuButton.Submenu&gt;\r\n        &lt;\/components:RadialMenuButton&gt;\r\n        &lt;components:RadialMenuButton Label=\"Halloween\" Icon=\"\ud83c\udf83\" \/&gt;\r\n    &lt;\/userControl:RadialMenu.Buttons&gt;\r\n&lt;\/userControl:RadialMenu&gt;\r\n<\/code><\/pre>\n<\/div>\n<p>If you build and run your app now, you will see that the outer rim of your food button automatically became enabled, got a little caret indicating an interaction, and opens up the submenu on button press.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-25-drawboard-tutorial2.gif\" alt=\"Screenshot of the &quot;Hello Radial Menu App&quot;\" \/><\/p>\n<p>Now, let\u2019s assume that we want to give users the option to choose the diameter of their pizza using an interactive gauge. <code class=\"highlighter-rouge\">RadialMenuButtons<\/code> can host various kinds of custom submenus &#8211; the control ships with two kinds, a long list selector and a meter selector. While we could add the meter in XAML, let\u2019s mix things up and do it in code-behind. First, find the pizza button in your XAML file and give it an <code class=\"highlighter-rouge\">x:name<\/code> (for instance <code class=\"highlighter-rouge\">PizzaButton<\/code>) so that we can easily access it from C#.<\/p>\n<p>Then, head over to <code class=\"highlighter-rouge\">MainPage.xaml.cs<\/code> and add a new method to your <code class=\"highlighter-rouge\">MainPage<\/code> class called <code class=\"highlighter-rouge\">SetupPizzaMeter<\/code>. Call it in your <code class=\"highlighter-rouge\">MainPage()<\/code>, right after <code class=\"highlighter-rouge\">InitializeComponent()<\/code>. Also, add a reference to <code class=\"highlighter-rouge\">RadialMenuControl.UserControl<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>using RadialMenuControl.UserControl;\r\nusing System.Collections.Generic;\r\nusing Windows.UI.Xaml.Controls;\r\n\r\nnamespace HelloRadialMenu\r\n{\r\n    public sealed partial class MainPage : Page\r\n    {\r\n        private void SetupPizzaMeter()\r\n        {\r\n        }\r\n\r\n        public MainPage()\r\n        {\r\n            this.InitializeComponent();\r\n\r\n            SetupPizzaMeter();\r\n        }\r\n    }\r\n}\r\n<\/code><\/pre>\n<\/div>\n<p>Let\u2019s add a <code class=\"highlighter-rouge\">MeterSubMenu<\/code> to your pizza button. The basics are obvious: It\u2019s a gauge with a start and end value, from which the user can pick one. In most cases, the intervals between useful values will vary. Take a font size selector as an example: A good selector includes the most common values, but then quickly starts jumping in greater intervals. 6,7,8,9 are there, but the next offered choice after 72 might be 94. The <code class=\"highlighter-rouge\">MeterSubMenu<\/code> enables you to configure intervals, managing all the difficult math behind the scenes.<\/p>\n<p>First, define your intervals by creating a new <code class=\"highlighter-rouge\">List&lt;MeterRangeInterval&gt;<\/code>, filling it with as many <code class=\"highlighter-rouge\">MeterRangeIntervals<\/code> as you want to. Each interval is configured with start and end value, start and end degree &#8211; and optionally also a tick interval, which describes the distance between visible tick markers. In our case, we\u2019ll add two:<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>private List&lt;MeterRangeInterval&gt; PizzaIntervals = new List&lt;MeterRangeInterval&gt;()\r\n{\r\n    new MeterRangeInterval\r\n    {\r\n       StartValue = 5,\r\n       EndValue = 20,\r\n       TickInterval = 1,\r\n       StartDegree = 0,\r\n       EndDegree = 220\r\n    },\r\n    new MeterRangeInterval\r\n    {\r\n        StartValue = 20,\r\n        EndValue = 34,\r\n        TickInterval = 2,\r\n        StartDegree = 220,\r\n        EndDegree = 330\r\n    }\r\n};\r\n<\/code><\/pre>\n<\/div>\n<p>Inside <code class=\"highlighter-rouge\">SetupPizzaMeter()<\/code>, we can now add and configure the custom submenu on the pizza button. To get going, you only have to configure the meter\u2019s total start and end values, the start angle, and the length of your gauge meter. Then, pass the intervals to the <code class=\"highlighter-rouge\">Intervals<\/code> property.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>private void SetupPizzaMeter()\r\n{\r\n    var pizzaGauge = new MeterSubMenu()\r\n    {\r\n        MeterEndValue = 34,\r\n        MeterStartValue = 5,\r\n        MeterRadius = 70,\r\n        StartAngle = -90,\r\n        MeterPointerLength = 70,\r\n        RoundSelectValue = true,\r\n        Intervals = PizzaIntervals\r\n    };\r\n\r\n    PizzaButton.CustomMenu = pizzaGauge;\r\n}\r\n<\/code><\/pre>\n<\/div>\n<p>In a real world scenario, somebody would have to be notified when the user\u2019s selected value changes. You can get the <code class=\"highlighter-rouge\">SelectedValue<\/code> from <code class=\"highlighter-rouge\">pizzaGauge<\/code> at any time (it doesn\u2019t have to be visible), but in this example, let\u2019s print a debug line as soon as the user selects a value:<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>pizzaGauge.ValueSelected += (s, e) =&gt;\r\n{\r\n    var selectedValue = (s as MeterSubMenu).SelectedValue;\r\n    Debug.WriteLine(\"Value changed to \" + selectedValue);\r\n};\r\n\r\nPizzaButton.CustomMenu = pizzaGauge;\r\n<\/code><\/pre>\n<\/div>\n<p>To test your interactive gauge out, build and run the app. Go to the food submenu and notice how the pizza button now has an enabled outer rim, which opens up the custom menu on button press. Drag the needle to your desired position and release to set the value. Observe the output window to see the value being reported.<\/p>\n<h4 id=\"toggle--radio-buttons\">Toggle &amp; Radio Buttons<\/h4>\n<p>Let\u2019s assume that in our food menu, users can\u2019t click the pizza button as many times as they want to &#8211; they can merely <em>choose<\/em> pizza. Even harsher, they don\u2019t get to combine it with other entr\u00e9es, but they may optionally select or deselect ice cream. This is simple to implement: Go back to your <code class=\"highlighter-rouge\">MainPage.xaml<\/code> and set the <code class=\"highlighter-rouge\">Type<\/code> property of all food buttons to either <code class=\"highlighter-rouge\">Radio<\/code> or <code class=\"highlighter-rouge\">Toggle<\/code>. In one given radial menu, only one radio button can be selected &#8211; while toggle buttons play nice with other selected buttons.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>&lt;components:RadialMenuButton Label=\"Food\" Icon=\"\ud83c\udf71\"&gt;\r\n    &lt;components:RadialMenuButton.Submenu&gt;\r\n        &lt;userControl:RadialMenu&gt;\r\n            &lt;userControl:RadialMenu.Buttons&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Fries\" Icon=\"\ud83c\udf5f\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Eggs\" Icon=\"\ud83c\udf73\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Toggle\" Label=\"Ice Cream\" Icon=\"\ud83c\udf68\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Noodles\" Icon=\"\ud83c\udf5c\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Burger\" Icon=\"\ud83c\udf54\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Pizza\" Icon=\"\ud83c\udf55\" x:Name=\"PizzaButton\" \/&gt;\r\n             &lt;\/userControl:RadialMenu.Buttons&gt;\r\n        &lt;\/userControl:RadialMenu&gt;\r\n    &lt;\/components:RadialMenuButton.Submenu&gt;\r\n&lt;\/components:RadialMenuButton&gt;\r\n<\/code><\/pre>\n<\/div>\n<h4 id=\"events\">Events<\/h4>\n<p>Unless you want to severely disappoint your users, clicking the buttons should trigger some kind of action in your app &#8211; so let\u2019s talk about events for a moment. In order for the control to be as flexible as possible, you can bind to all kinds of events. Each <code class=\"highlighter-rouge\">RadialMenuButton<\/code> as well as the center button has events for pointer presses and releases for both the inner and the outer portion (which includes mouse, touch, and stylus interactions).<\/p>\n<p>Let\u2019s assume that we want to print a debug line whenever the user presses the top-level food button. In your <code class=\"highlighter-rouge\">MainPage.xaml<\/code>, find the food button. Make use of Visual Studio\u2019s amazing IntelliSense and let it create a new event handler for the <code class=\"highlighter-rouge\">InnerArcReleased<\/code> event.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>&lt;components:RadialMenuButton Label=\"Food\" Icon=\"\ud83c\udf71\" InnerArcReleased=\"RadialMenuButton_InnerArcReleased\"&gt;\r\n<\/code><\/pre>\n<\/div>\n<p>Open <code class=\"highlighter-rouge\">MainPage.xaml.cs<\/code> and find the freshly minted event handler. In there, simply log that we better start cooking:<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>private void RadialMenuButton_InnerArcReleased(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)\r\n{\r\n    Debug.WriteLine(\"Get cooking!\");\r\n}\r\n<\/code><\/pre>\n<\/div>\n<p>In order to be fancy, the selected food option should be somehow reflected in the top-level menu. As soon as the user leaves the food menu to go back to the main level menu, we want to check if a food option has been selected &#8211; and if so, we want to change the food button icon and label. Open <code class=\"highlighter-rouge\">MainPage.xaml<\/code> and find the <code class=\"highlighter-rouge\">RadialMenu<\/code> for your food options. In there, use IntelliSense to create a new handler for the <code class=\"highlighter-rouge\">CenterButtonTapped<\/code> event. Also, let\u2019s give the food button a <code class=\"highlighter-rouge\">x:Name<\/code> so that we can easily access it from C#.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>&lt;components:RadialMenuButton x:Name=\"FoodButton\" Label=\"Food\" Icon=\"\ud83c\udf71\" InnerArcReleased=\"RadialMenuButton_InnerArcReleased\"&gt;\r\n    &lt;components:RadialMenuButton.Submenu&gt;\r\n        &lt;userControl:RadialMenu CenterButtonTapped=\"RadialMenu_CenterButtonTapped\"&gt;\r\n            &lt;userControl:RadialMenu.Buttons&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Fries\" Icon=\"\ud83c\udf5f\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Eggs\" Icon=\"\ud83c\udf73\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Toggle\" Label=\"Ice Cream\" Icon=\"\ud83c\udf68\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Noodles\" Icon=\"\ud83c\udf5c\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Burger\" Icon=\"\ud83c\udf54\" \/&gt;\r\n                &lt;components:RadialMenuButton Type=\"Radio\" Label=\"Pizza\" Icon=\"\ud83c\udf55\" x:Name=\"PizzaButton\" \/&gt;\r\n             &lt;\/userControl:RadialMenu.Buttons&gt;\r\n        &lt;\/userControl:RadialMenu&gt;\r\n    &lt;\/components:RadialMenuButton.Submenu&gt;\r\n&lt;\/components:RadialMenuButton&gt;\r\n<\/code><\/pre>\n<\/div>\n<p>In <code class=\"highlighter-rouge\">MainPage.xaml.cs<\/code>, we can now add the logic that will update the icon of the top level food item. Basically, we want to check if the menu\u2019s <code class=\"highlighter-rouge\">Pie<\/code>, the data structure managing all the currently visible buttons, has a selected radio button. If so, we use that selected item\u2019s label and icon to update our food button.<\/p>\n<p>&nbsp;<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>private void RadialMenu_CenterButtonTapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)\r\n{\r\n    var sendingMenu = sender as RadialMenu;\r\n    if (sendingMenu != null &amp;&amp; sendingMenu.Pie.SelectedItem != null)\r\n    {\r\n        FoodButton.Label = sendingMenu.Pie.SelectedItem.Label;\r\n        FoodButton.Icon = sendingMenu.Pie.SelectedItem.Icon;\r\n    }\r\n}\r\n<\/code><\/pre>\n<\/div>\n<p>To see all that magic in action, build and run the app.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-25-drawboard-tutorial3.gif\" alt=\"Screenshot of the &quot;Hello Radial Menu App&quot;\" \/><\/p>\n<p>If you just want to see the source code in action, head over to GitHub, <a href=\"https:\/\/github.com\/CatalystCode\/radial-menu\/tree\/CaseStudyDemo\/HelloRadialMenu\">where the source code for \u201cHelloRadialMenu\u201d is readily available<\/a>.<\/p>\n<h4 id=\"doing-more\">Doing More<\/h4>\n<p>The tutorial just covered the basics of the radial menu &#8211; depending on your use cases and creativity, you\u2019ll quickly notice that the modularity, opportunity to configure each piece individually, and availability of flexible events makes a large number of scenarios possible. Two small examples would be the custom input &#8211; or the long list selector:<\/p>\n<p><img decoding=\"async\" src=\"\/https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-25-drawboard-list.gif\" alt=\"Gif: List Selector\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-25-drawboard-custom.gif\" alt=\"Gif: Custom Input\" \/><\/p>\n<p>The control has been released using the MIT License and can be used free of charge for both commercial and personal projects (for details, please see the <a href=\"https:\/\/github.com\/CatalystCode\/radial-menu\/blob\/master\/LICENSE\">LICENSE<\/a>). In case you\u2019re wondering about individual properties, methods, and events available on the classes in the control, take a look at the <a href=\"https:\/\/github.com\/CatalystCode\/radial-menu\/blob\/master\/README.md\">README<\/a> &#8211; they\u2019re all documented there.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We built a beautiful Radial Menu Control for Drawboard, a PDF Reader preinstalled on all Surface devices. It&#8217;s open source &#8211; so go ahead and spice up your XAML UWP Apps!<\/p>\n","protected":false},"author":21345,"featured_media":12794,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[16],"tags":[113,159,255,364,370,373,395],"class_list":["post-2156","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","tag-c","tag-drawboard","tag-microsoft-surface","tag-ui","tag-universal-windows-platform-uwp","tag-ux","tag-xaml"],"acf":[],"blog_post_summary":"<p>We built a beautiful Radial Menu Control for Drawboard, a PDF Reader preinstalled on all Surface devices. It&#8217;s open source &#8211; so go ahead and spice up your XAML UWP Apps!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2156","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/users\/21345"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/comments?post=2156"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2156\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media\/12794"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media?parent=2156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/categories?post=2156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/tags?post=2156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}