Dynamic number of Tabs in MulitLayoutPanel

So I am basically trying to create x number of tabs with x number of pages based on data from an API.
The data from the API looks something like this:

{
"sections": [
	{
		"sectionid": 29,
		"name": "Group Stage | Day 1 | 5th",
		"groups": [
			{
				"groupid": 118,
				"name": "GroupA | Match 1",
			},...
			]
	},...
	]
}

I expose an Observable containing the sections and sectionsize (which is sections.length), and then have this code:

<StackPanel Dock="Top" Background="#bdc3c7">
	<StatusBarBackground />
	<iOS.StatusBarConfig Style="Light"/>

	<MultiLayoutPanel Height="50" ux:Name="tabBar">
		<GridLayout ColumnCount="{sectionsize}" Rows="1" />
		<Each Items="{sections}">
			<Panel ux:Name="{sectionid}">
				<Tab Text="{sectionid}">
					<!--<Set nav.Active="{name}" />-->
				</Tab>
			</Panel>
		</Each>
	</MultiLayoutPanel>

</StackPanel>

<PageControl ux:Name="nav">
	<Each Items="{sections}">
		<Page ux:Name="{name}">
			<WhileActive Threshold="0.5">
				<!--<Set tabBar.LayoutElement="{sectionid}" />-->
			</WhileActive>
			<StackPanel Orientation="Vertical">
				<Text Value="{name}" />
				<Each Items="{groups}">
					<Text Value="{name}"/>
				</Each>
			</StackPanel>
		</Page>
	</Each>
</PageControl>

The first problem is ColumnCount within the GridLayout. I can set this value to 6, and it works, but I want it to be the number of sections, and it doesn’t seem to work with the sectionsize variable.

Secondly, I can’t make the ux:Name of panel and page dynamic, then referring to them (see the code that’s commented out).

I wonder what would be the easiest/best way/workaround to make this work.

Hi,

The general idea is to use <AlternateRoot ParentNode="tabBar"> from within the page. This allows you to inject one element per page into the tab bar, while being declared in the same scope as the page.

This is pseudo code:

<MultiLayoutPanel Height="50" ux:Name="tabBar">
    <GridLayout ColumnCount="{sectionsize}" Rows="1" />
</MultiLayoutPanel>
...
<PageControl ux:Name="nav">
    <Each Items="{sections}">
        <Page ux:Name="page">
        	<AlternateRoot ParentNode="tabBar">
        		<Panel ux:Name="{sectionid}">
	                <Tab Text="{sectionid}">
	                    <Set nav.Active="page" />
	                </Tab>
	            </Panel>
	            <WhileActive Threshold="0.5">
	               <Set tabBar.LayoutElement="self" />
	            </WhileActive>
		    </AlternateRoot>
            <StackPanel Orientation="Vertical">
                <Text Value="{name}" />
                <Each Items="{groups}">
                    <Text Value="{name}"/>
                </Each>
            </StackPanel>
        </Page>
    </Each>
</PageControl>

As for why ColumnCount="{sectionsize}" doesn’t work, I have no idea. That should work. I’m guessing it will sort itself out once you get the header injection straight. Otherwise, please provide a test case of that issue in isolation, please.

Thanks, it worked with a little tweaking.

<PageControl ux:Name="nav">
	<Each Items="{sections}">
		<Page ux:Name="page">
			<AlternateRoot ParentNode="tabBar">
				<Panel ux:Name="self">
					<Tab Text="{sectionid}">
						<Clicked>
							<Set nav.Active="page" />
						</Clicked>
					</Tab>
				</Panel>
			</AlternateRoot>

			<WhileActive Threshold="0.5">
				<Set tabBar.LayoutElement="self" />
			</WhileActive>
			<StackPanel Orientation="Vertical">
				<Text Value="{name}" />
				<Each Items="{groups}">
					<Text Value="{name}"/>
				</Each>
			</StackPanel>
		</Page>
	</Each>
</PageControl>

However, sectionsize is not working properly, and it might be because I didn’t set up the Observable correctly.
I’ve tried some different things but it doesn’t show up correctly.

var sections = Observable();

var sectionsize = sections.length;
var sectionsize = Observable(sections.length);

How would be the correct way to do this?

.length is not a reactive operator. Try this instead:

 var sectionsize = sections.count();

It worked, thank you!