Gotcha: custom Microsoft Band page shows only data in last added UI element
Today I finally nailed a very odd issue in the Microsoft Band SDK - or actually, my understanding thereof. For my current research project, I am building a custom UI on my Microsoft Band. I should contain two panels: one with a text, an icon and a button, and a second panel containing two texts. Details of how to setup up something like this, can be found in the band samples.
Building a Band UI is not for the faint hearted, it includes building the UI from code without any kind of designer. Filling those UI elements with a value then is a separate step, which contains quite a big gotcha that you cannot derive from the samples.
My Band UI creation code is like this:
private IEnumerable<PageLayout> BuildTileUi()
{
var bandUi = new List<PageLayout>();
var page1Elements = new List<PageElement>
{
new Icon {ElementId = IconId, Rect = new PageRect(60,10,24,24)},
new TextBlock {ElementId = TextTemperatureId, Rect = new PageRect(90, 10, 50, 40)},
new TextButton {ElementId = ButtonToggleFanId, Rect = new PageRect(10, 50, 220, 40),
HorizontalAlignment = HorizontalAlignment.Center}
};
var firstPanel = new FilledPanel(page1Elements) { Rect = new PageRect(0, 0, 240, 150) };
var page2Elements = new List<PageElement>
{
new TextBlock {ElementId = TextTimeId, Rect = new PageRect(10, 10, 220, 40)},
new TextBlock {ElementId = TextDateId, Rect = new PageRect(10, 58, 220, 40)}
};
var secondPanel = new FilledPanel(page2Elements) { Rect = new PageRect(0, 0, 240, 150) };
bandUi.Add(new PageLayout(firstPanel));
bandUi.Add(new PageLayout(secondPanel));
return bandUi;
}
That is quite a handful, right? Then for setting values to those UI element, I had this little piece of code:
private List<PageData> BuildTileData1(string timeText,
string dateText,
string temperature,
string buttonText)
{
var result = new List<PageData>
{
new PageData(Page2Id, 1,
new TextBlockData(TextTimeId, timeText)),
new PageData(Page2Id, 1,
new TextBlockData(TextDateId, dateText)),
new PageData(Page1Id, 0, new IconData(IconId, 1)),
new PageData(Page1Id, 0,
new TextBlockData(TextTemperatureId, temperature)),
new PageData(Page1Id, 0, new TextButtonData(ButtonToggleFanId, buttonText))
};
return result;
}
And this is set to my tile using bandClient.TileManager.SetPagesAsync. Which gave me a quite puzzling result: only the last element on each page actually had a value. So that means only the datetext and the button actually showed text. As the sample in the Band SDK samples only uses one UI element, I was like, repeat adding PageData elements, right?
Wrong!
It turns out you can only add values to a PageData element once per SetPagesAsync call. So what you need to do, actually, is:
private List<PageData> BuildTileData(string timeText,
string dateText,
string temperature,
string buttonText)
{
var result = new List<PageData>
{
new PageData(Page2Id, 1,
new TextBlockData(TextTimeId, timeText),
new TextBlockData(TextDateId, dateText)),
new PageData(Page1Id, 0,
new IconData(IconId, 1),
new TextButtonData(ButtonToggleFanId, buttonText),
new TextBlockData(TextTemperatureId, temperature)),
};
return result;
}
See the difference? Only add 2 PageData elements, one for every Page, not one for every page element data object. Maybe elementary, but I overlooked it. For quite some time. The constructors of PageData give a bit of a hint:
public PageData(Guid pageId, int pageLayoutIndex, IEnumerable<PageElementData> values); public PageData(Guid pageId, int pageLayoutIndex, params PageElementData[] values);
as the third parameter is not a page element data object but a list of it. The thing is, I created the UI on demand (when I tapped the tile) and then it worked as expected - but not the seconds time around.
It took me quite some time to figure this one out, so I thought it best to blog about it right away. Maybe I am giving help here, maybe I am just documenting my own stupidity, but nevertheless ;)
I skip the demo sample this time - if you run into this problem, you are quite far with the Band UI already, and the demo I am working on contains this code anyway and will - hopefully - arrive online soon anyway. Attentive readers will have some inkling of what that demo exactly comprises.
Happy Band coding!
MVP Profile
Try my app HoloATC!
HoloLens 2
Magic Leap 2
Meta Quest
Android phones
Snap Spectacles
Buy me a drink ;)
BlueSky
Mastodon
Discord: LocalJoost#3562