Visual Studio Designer for Microsoft BandRequirements: Visual Studio 15 with Update 1 Microsoft Band SDK: http://developer.microsoftband.com/ The designer allows creation of custom tile layouts for Microsoft Band. It does not provide its own type of project, nor does it take dependency on particular version of Microsoft Band SDK. Once installed, a developer can add a new “Microsoft Band Tile Layout” item to a C# project, visually design the layout of as many tiles as needed and consume the generated code to easily deploy the layouts to the Band and send data updates. Please review the TileEvents sample from Microsoft Band SDK to learn how to develop applications for the Microsoft Band. Getting Started with the DesignerYour first step would be creation of a project for your application. Most likely it will be Universal or Windows Phone 8.1 one. Then you would use Add New Item to add your custom tile layout item.
There is a Visual Studio limitation, which prevents the designer from working as part of the shared projects like shown in the picture below. The designer will work but it will not be able to generate the code file. The layout item needs to be placed in the supported project. In simple cases like below the generated code by the designer in the parent project will be visible automatically in the shared project but in cases whenTileEvent.Shared project is really shared among other projects (WP8.1 and Universal, for example) some kind of file linking needs to be established. An example of such sharing is realTileEvents project from Band SDK samples. When you add the item for the first time, you will be asked whether you trust it or not. It is a standard Visual Studio warning when using project item packages. Once you choose to trust the package, Visual Studio will not ask you again until you reinstall the designer. The designer installs Band related tools to the Toolbox. You will want to use appropriate zoom level and have Properties panel visible (F4). Any time you click on the tile image in the designer (not on an element) the designer selects a Layout object and you can change its properties. For example, you can change Version to 1 in the Properties panel and the size of the layout will change appropriately to reflect the view portal for Band 1. Start dragging items from the Toolbox to the tile on the designer. First element must be a Panel: Filled Panel, Flow Panel or Scroll Flow Panel. It will contain all other elements, including other panels. You can alsodouble click an element in the Toolbox to add it to the tile. The designer targets one tile layout. For multiple tiles add more “Microsoft Band Tile Layout” items to your project. ZoomZoom is controlled with: 1. The combo-box at the bottom of the design surface. 2. Ctrl + Mouse Wheel actions when the cursor of the mouse is over the tile object. Selecting ElementsMouse Ctrl + Click allows multiple selection. Some elements might not be visible in the view due to their size being 0, or them being hidden behind other elements. You can locate such elements with context menu, which shows the elements in Z order.
Properties panel also allows locating and selecting elements. Giving an element a name (Name property accessed with Properties panel) makes finding it easier and helps accessing it from code. Operations with Multiple SelectionPlease explore the context menu. You can use clipboard operations to move and copy elements within the same or across different designers and even Visual Studio instances (the clipboard format is Text). Z-order is changed with context menu | Order | through commands like “Bring to Front”. In the Flow Panel and Scroll Flow Panel, the order of elements is controlled by their Z order so operations like “Send Backward” rearrange the horizontal or vertical ordering of elements in these panels. Remember, Z-Order of elements on the Microsoft Band differs from other frameworks. An item added to a Flow Panel goes at the end of the list but to the bottom of Z-order. Context Menu | Align and Layout contain many operations to adjust left or right edges of several elements or make them of the same size. The element youCtrl + Click first (has thicker selection frame) becomes the source for the operation. For example, other selected elements adjust to its Width if “Make Same Width” command is used.
You can assign the same value to a property of all currently selected elements. But the property must be shared by all of them. Here is an example of setting Left Margin for 3 selected elements. Keyboard SupportYou can navigate between the elements with the keyboard. 1. Tab and Shift + Tab will navigate to the next or previous element. 2. Arrow keys will move the selected elements. 3. Shift + Arrow keys will resize the selected elements. Text In-place EditingFor the elements: Text Block, Wrapped Text Block and Text Button, it is possible to edit their text in-place (besides the usual property changes on the Properties panel). UseF2 or Click the element when it was already selected. The designer will go into in-place text edit mode and you will be able to select, cut, copy and paste text across several elements. Once you enter in-place edit mode, all elements become in-place editable. Esc cancel all edits and the contents ofall elements from the beginning of the last edit operation will be reverted. To commit the changes hitEnter. Wrapped Text Block element handles Enter itself because this way you can terminate lines, so you will need to click outside of the element to complete the edit of this text block. Alternatively, you canTab to the nearest non-wrapped text block and hit Enter.
Text boxes can have either automatic width or automatic height. When you change the text inside them, they are resized. If you do change their size with the mouse, the Auto property is reset. The elements keep their sizes when you change the text. To return the Auto property behavior back either use Properties panel or Context Menu | Layout | Reset Size. This also works for icons. Dealing with Scroll Flow ListsIf you keep adding more elements to Flow List containers, they will be clipped out of the visible view. Flow List does not scroll so to delete an out-of-view element you can use Context Menu | Set Selection and then delete the element. The designer will show the selection frame somewhere outside of the Flow List. Alternatively, you can use Tab key to navigate to the hidden element. Scroll Flow List can scroll. If you end up in the situation like above, you have the option to scroll the list and bring the item into view for modification and verification. 1. Use mouse wheel on the Scroll Flow List. The contents will scroll. 2. Click an item in the Scroll Flow List and hit Tab key. That will scroll the list, bringing the hidden elements into view as they become focused. IconsTo add an icon, first drag it from the Toolbox to the target panel. Then have the image added to your project in some folder. For example, yourAssets folder contains image SSS.png which you want to use. Modify the icon’sSource property to reflect the path to the image as “Assets/SSS.png”. Once you see the icon loaded, use the Context Menu | Layout | Reset Size to have the element pick up the size of the icon. Pressed Color of ButtonsButtons on the band can change their color when pressed. You can assign the color in the Properties window. To see how the color would look like in the designer you can move the mouse cursor over the button on the designer and press and hold Left Mouse button. The designer will change the color of the button. This also means that when you drag that button to a different location the button will be shown with the color assigned for its “pressed” state. Once you release the mouse button the color will be changed back to normal. Code GenerationConsuming the Layout with CodeEach time the designer saves its content, Visual Studio automatically generates C# source code to consume the layout. The code file is a child element of the layout element in the Solution. If you rename the layout file, the code file gets renamed too and the C# code gets regenerated. The class name and its namespace reflect the name of the layout file and its location.
The generated class exposes the layout, the data which has been entered at design time, the ability to alter the data and update the band either fully or incrementally. The examples below assume you have BandTileLayout1.msblt in your project. The code uses classes from Microsoft Band SDK available at http://developer.microsoftband.com/. Example using (IBandClient bandClient = awaitBandClientManager.Instance.ConnectAsync(pairedBands[0])) { vardesigned = newBandTileLayout1(); … skipped …
BandTile myTile =newBandTile(myTileId) { … skipped … };
myTile.PageLayouts.Add(designed.Layout); … skipped …
await designed.LoadIconsAsync(myTile);
await bandClient.TileManager.AddTileAsync(myTile);
… skipped …
await bandClient.TileManager.SetPagesAsync( myTileId, … skipped … designed.Data.All));
… skipped … } Adjustments on top of the Designed ContentYou can also alter the designed content programmatically before applying it to theTileManager. The designed instance you have instantiated exposesPageLayout referring to regular SDK objects, which is a tree of PageElement objects. You can choose to access specific elements by traversing the tree but there is an easier way. Any time you give a name to the element when designing, the generated class exposes that element as internal field with the same name. The fields for the elements you did not explicitly name get generated as private. classBandTileLayout1 { … skipped … internalTextBlocktextA = newTextBlock(); internalTextBlockDatatextAData =newTextBlockData(4,"A"); … skipped … }
When altering the designed layout in code, you will get help from IntelliSense. The correspondingPageElementData field has the same name as its PageElement field plus Data suffix. Example of altering the data for just a few elements and sending update to the band designed.iconData.IconIndex = (ushort)(myTile2.AdditionalIcons.Count - 1 + 2);// 2 since the first 2 are used by the tile itself designed.textAData.Text = "ModifiedText"; designed.btnData.Text = "ModifiedButton";
await bandClient.TileManager.SetPagesAsync(myTileId2, new PageData(Guid.NewGuid(), 0, designed.Data.All));
If you want to modify a designed PageElement you modify its properties before sending to the tile manager. designed.filledButton.BackgroundColor =newBandColor(128, 0, 0); What if You Need an Alternative Way to Load Icons?The generated code contains methods to load the icon content you used at design time. At this moment the generated code is not self-sufficient. The icon binary is still somewhere in the resources and is loaded using the URI resolved from the contents of the Source property of Icon object. In case if the generated code does not work, you have the ability to provide your own and keep usingawaitdesigned.LoadIconsAsync(myTile). These are the 2 properties from generated code which might help. publicFunc<string,Task<BandIcon>> LoadIconMethod { get; set; }
publicFunc<string,string> AdjustUriMethod { get; set; }
If your debugging shows that the problem is in URI being incorrect then you have a chance to assign your custom URI adjusting function toAdjustUriMethodproperty of the designed object. In case if you need completely different icon loading code you assign it to propertyLoadIconMethod. You can always skip calling designed.LoadIconsAsync and manage data updates on your own modifying PageElementData fields and calling designed.Data.All as has been shown earlier. Example of a Tile with Multiple LayoutsMicrosoft Band allows 8 layouts per tile. To create a tile with 2 layouts, using the designer you would add 2 items to your project and design them separately.
Thus your project will get 2 layout classes and you can consume them with the code like below. var designed = new BandTileLayout1(); var designed2 = new BandTileLayout2(); myTile.PageLayouts.Add(designed2.Layout); // The layouts are added to to the front myTile.PageLayouts.Add(designed.Layout);
// Remove the Tile from the Band, if present. An application won't need to do this everytime it runs. // But in case you modify this sample code and run it again, let's make sure to start fresh. await bandClient.TileManager.RemoveTileAsync(myTileId);
await designed.LoadIconsAsync(myTile); await designed2.LoadIconsAsync(myTile);
// Create the Tile on the Band. await bandClient.TileManager.AddTileAsync(myTile); await bandClient.TileManager.SetPagesAsync (myTileId, new PageData(new Guid("5F5FD06E-BD37-4B71-B36C-3ED9D721F200"), 0, designed2.Data.All)); await bandClient.TileManager.SetPagesAsync (myTileId, new PageData(new Guid("5F5FD06E-BD37-4B71-B36C-3ED9D721F300"), 1, designed.Data.All));
Handling EventsIt is natural to expect from any form-like designer to double click a button and have an event handler code automatically generated. Unfortunately, because the source of events is outside of the scope of the objects controlled by the designer, the designer cannot automatically generate event-handling code. The source of events is Tile Manager of a Band Client. The designer does not restrict the developers in how they want to organize their code. Any layout produced by the designer can be added one or more times to any tile and deployed to any client. So the events handlers have to be coded manually, similarly to what SDK samples have demonstrated. Here is an example: bandClient.TileManager.TileButtonPressed += (s, args) => { var a = Dispatcher.RunAsync( CoreDispatcherPriority.Normal, async () => { if (handlingTileButton) return;
handlingTileButton = true; try { var targetEventId = args.TileEvent.ElementId;
if (targetEventId == (ushort)designed.IncButton.ElementId) ++buttonPressedCount; else if (targetEventId == (ushort)designed.DecButton.ElementId) --buttonPressedCount;
designed.MyTextBlockData.Text = buttonPressedCount.ToString();
await bandClient.TileManager.SetPagesAsync( myTileId, new PageData(new Guid("5F5FD06E-BD37-4B71-B36C-3ED9D721F200"), 0, designed.Data.All()));
} catch(Exception) { } finally { handlingTileButton = false; } } ); };
Third Party NoticesThis Third Party Notices file provides notices and information about the third party code or other materials listed below ("Third Party Code") which are included with the Microsoft Product. Microsoft reserves all other rights to the Third Party Code not expressly granted by Microsoft, whether by implication, estoppel or otherwise. The notices and licenses below are provided for informational purposes only. Json.NET 8.0.1 | MIT License http://www.newtonsoft.com/json Copyright (c) 2007 James Newton-King Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |