Skip to content

Instantly share code, notes, and snippets.

@PureWeen
Last active April 11, 2019 22:57
Show Gist options
  • Save PureWeen/698ea2fc99d2482e530f30993fd15697 to your computer and use it in GitHub Desktop.
Save PureWeen/698ea2fc99d2482e530f30993fd15697 to your computer and use it in GitHub Desktop.
Routing URI Spec
Relative push - edit
Relative replace - \\edit
absolute push - \edit or if your shell route is unique shell\edit
absolute replace - \\\edit or if your shell route is unique \\shell\edit

Route construction and GoToAsync behavior

Api Changes

  • Remove Scheme and Host from Shell. These don't serve any purpose related to the shell. Right? No one in the context of the app will ever use these values. They seem to only serve a purpose for app deeplinking when needing to associate a scheme/path with your app

  • Add assembly attributes you can use to define for scheme routing to a shell. With an assembly attribute we can add more compile time behaviors. The hope here will be to auto generate things needed for applinks into the plist and android manifest files.

  • Shell.Navigation.GoToAsync (maybe we just call this PushAsync to keep the api consistent)

  • Shell.Navigation.GoBack

  • Shell.Navigation.GoForward

  • Shell.Navigation.Stack

Route Definitions

Route structure

/route (required) / pages (optional ? QueryParams (optional)

Routes are defined as things that belong to a ShellContent. These are screens that exist in the Shell hierarchy. Pages don't exist in the visual hierarchy and are pushed onto the stack more on demand. Pages can be registered at the root of the shell.

Example: Given the following URI /store/category/edit

The routing system will try to match the entire route and then pop segments until the route is found. Any segments removed are just interpreted as separate pages. So if the shellcontent route is /shell/store/category

The root will be set to the shell content at /shell/store/category. The routing system will then search in the following order for a page with the route edit

//store/category/edit
//store/edit
//edit

Once the page is found that is what the visible content will be set to. This will not create a page stack, the stack will only have one item on it.

You can also register routes at a hierarchy for example

RegisterRoute("/shell/store/category/edit", typeof(EditCategory));
RegisterRoute("/shell/people/category/edit", typeof(EditPeople));

When decomposing the route it'll try to match routes mapped specifically to ShellContent so that it can know what to set the root to and then it will search for page matches. See examples below for clarity

Route Code Samples

Given the following setup

<Shell>
    <FlyoutItem Route="xamtube">
		<Tab Route="home" />
		<Tab Route="library" />
		<Tab Route="store" />
	</FlyoutItem>
</Shell>
RegisterRoute("LoginPage", typeof(LoginPage));
RegisterRoute("StoreItem", typeof(StoreItem));
RegisterRoute("/xamtube/library/edit", typeof(EditLibraryContentPage));
RegisterRoute("/xamtube/library/store", typeof(EditStoreContentPage));
RegisterRoute("edit", typeof(EditSettings));

Set root of shell to default content page for xamtube

GotoAsync("//xamtube")
// or
GotoAsync("/xamtube")

Set xam tube as root of shell and activate library tab

GotoAsync("//xamtube/library") 

User will only see Login Page and no Shell Navigation

GotoAsync("//LoginPage") 

Store tab will be set to first element in stack and then Store Item page will get set as the content. The StoreItem page will be displayed nested in the tab view and the stack will only contain one item.

GotoAsync("//xamtube/store/StoreItem?ItemId=123") 

Not sure if this is relevant but messing around with nested parameters

GotoAsync("//xamtube/store%3FSomeParameter%3D12/StoreItem?ItemId=123") 

This creates a navigation stack with the home tab and then the store tab. If the user hits the back button it will go to the home page

GotoAsync("//xamtube/home") 
GotoAsync("xamtube/store") 

This will set xamtube/library as root of shell. The router will now look at the current hierarchy for a route called edit. If nothing is found then it will search up the route hierarchy until it finds a page called edit

GotoAsync("/xamtube/library/edit") 

Existing INavigation mappings

public interface INavigation
{
	// Contains stack of Pages on shell contents
	IReadOnlyList<Page> NavigationStack { get; }
	
	//can be used to insert a page somewhere on stack. This is the same as pushing a PageContent
	void InsertPageBefore(Page page, Page before);
	
	// locate content in stack that matches this page and remove it from the stack
	void RemovePage(Page page);
	
	// Go back in stack
	Task<Page> PopAsync();
	
	// Go back in stack
	Task<Page> PopAsync(bool animated);
	
	// pop everything except base
	Task PopToRootAsync();
	
	// pop everything except base
	Task PopToRootAsync(bool animated);

	// push a PageContent onto Shell stack
	Task PushAsync(Page page);

	// push a PageContent onto Shell stack
	Task PushAsync(Page page, bool animated);
	
	// push a PageContent onto Shell stack without navigation structure (at some point we will let people make this prettier)
	Task PushModalAsync(Page page);
	
	// push a PageContent onto Shell stack without navigation structure (at some point we will let people make this prettier)
	Task PushModalAsync(Page page, bool animated);
	
	// Contains stack of any modal pages pushed
	IReadOnlyList<Page> ModalStack { get; }
	
	// Close current Modal page
	Task<Page> PopModalAsync();
	
	// Close current Modal page
	Task<Page> PopModalAsync(bool animated);

}

Alternate routing ideas

Given

<Shell>
    <FlyoutItem Route="xamtube">
		<Tab Route="home" />
		<Tab Route="library" />
		<Tab Route="store" />
	</FlyoutItem>
</Shell>

use // inside uri to build navigation stack

GotoAsync("/xamtube/home//xamtube/library");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment