Created
June 5, 2019 19:40
-
-
Save TheBaileyBrew/f8a9d2e4668da3ec9bff9bf86d32d951 to your computer and use it in GitHub Desktop.
Creating FlyoutItems Dynamically in Xamarin.Forms Shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//I actually have this separated out into a model class, but it could technically be internal like this | |
internal class NavigationItem { | |
public string Title { get; set; } ////This pairs with ShellItem.Title | |
public DataTemplate Template { get; set; } ////This pairs with ShellItem.ContentTemplate | |
public ImageSource Image { get; set; } ////This pairs with ShellItem.Icon | |
public string Route { get; set; } ////This pairs with ShellItem.Route | |
public List<ShellContent> Tabs { get; set; } ////This pairs with ShellItem.Tab | |
public bool HasImage => Image != null; ////These are optional, and just for validation purpose | |
public bool HasNavigation => Template != null; ////These are optional, and just for validation purpose | |
public bool HasTabs => Tabs != null; ////These are optional, and just for validation purpose | |
} | |
//This is for a single item (IMAGINE A HEADER) | |
public List<NavigationItem> NavigationItemHeader { get; set; } = new List<NavigationItem> | |
{ | |
new NavigationItem | |
{ | |
Title = "Header" | |
} | |
}; | |
//This is for a single item (IMAGINE AN ITEM WITH LINK TO MULTIPLE TABS) | |
public List<NavigationItem> NavigationItemSearch { get; set; } = new List<NavigationItem> | |
{ | |
new NavigationItem{ | |
Title = "Item Search", Route = "ITEM INQUIRY", Tabs = new List<ShellContent> | |
{ | |
new ShellContent{ | |
Title = "Item Search", | |
Route = "ITEM INQUIRY", | |
ContentTemplate = new DataTemplate(typeof(ItemSearchPage))}, | |
new ShellContent{ | |
Title = "Item Detail", | |
Route = "ITEM DETAIL", | |
ContentTemplate = new DataTemplate(typeof(ItemDetailPage))} | |
} | |
} | |
}; | |
//This is for all other single items (IMAGINE ALL OTHER NORMAL FLYOUT ITEMS) | |
public List<NavigationItem> NavigationItemList { get; set; } = new List<NavigationItem> | |
{ | |
new NavigationItem{ | |
Title = "New Items", | |
Route = "NEWITEMS", | |
Template = new DataTemplate(typeof(NewItemsPage))}, | |
new NavigationItem{ | |
Title = "Discontinued Items", | |
Route = "DISCITEMS", | |
Template = new DataTemplate(typeof(DiscontinuedItemsPage))}, | |
new NavigationItem{ | |
Title = "Outs", | |
Route = "OUTS", | |
Template = new DataTemplate(typeof(OutsPage))}, | |
new NavigationItem{ | |
Title = "Recalls", | |
Route = "RECALLS", | |
Template = new DataTemplate(typeof(RecallsPage))}, | |
new NavigationItem{ | |
Title = "Rankings", | |
Route = "RANKINGS", | |
Template = new DataTemplate(typeof(HomePage))}, | |
new NavigationItem{ | |
Title = "Featured Items", | |
Route = "FEATURED", | |
Template = new DataTemplate(typeof(HomePage))}, | |
new NavigationItem{ | |
Title = "Item Authorization", | |
Route = "ITEMAUTH", | |
Template = new DataTemplate(typeof(HomePage))}, | |
new NavigationItem{ | |
Title = "Item Allowances", | |
Route = "ALLOWANCES", | |
Template = new DataTemplate(typeof(HomePage))}, | |
}; | |
//And this is how you build the items in code behind... | |
//Build Header | |
NavigationItemHeader.Select(x => new FlyoutItem | |
{ | |
Title = x.Title, | |
}).ForEach(Items.Add); | |
//Build Item Search Grouping | |
NavigationItemSearch.Select(x => new FlyoutItem | |
{ | |
FlyoutDisplayOptions = FlyoutDisplayOptions.AsSingleItem, ////Defines the Display Option (as single or as multiple) | |
Title = x.Title, ////Defines the Title text of the flyout | |
Route = x.Route, ////Defines the Route (if applicable) | |
Items = ////Defines the ShellItems hidden behind the FlyoutItem | |
{ | |
new Tab{ | |
Title = x.Tabs[0].Title, ////Since my internal class NavigationItem set Tabs as a list, you want to build it for whatever you put in the list<> above | |
Items = { | |
new ShellContent | |
{ | |
Title = x.Tabs[0].Title, | |
Route = x.Tabs[0].Route, | |
ContentTemplate = x.Tabs[0].ContentTemplate | |
} | |
} | |
}, | |
new Tab{ | |
Title = x.Tabs[1].Title, | |
Items = { | |
new ShellContent | |
{ | |
Title = x.Tabs[1].Title, | |
Route = x.Tabs[1].Route, | |
ContentTemplate = x.Tabs[1].ContentTemplate | |
} | |
} | |
} | |
} | |
}).ForEach(Items.Add); | |
//Build Item Search Grouping | |
NavigationItemList.Select(x => new FlyoutItem | |
{ | |
Title = x.Title, ////Defines the Title text of the flyout | |
Route = x.Route, ////Defines the Route (if applicable) | |
Items = //Defines the ShellItems hidden behind the FlyoutItem | |
{ | |
new Tab{ | |
Title = x.Title, ////Since my internal class NavigationItem set Tabs as a list, you want to build it for whatever you put in the list<> above | |
Items = { | |
new ShellContent | |
{ | |
Title = x.Title, | |
Route = x.Route, | |
ContentTemplate = x.ContentTemplate | |
} | |
} | |
} | |
} | |
}).ForEach(Items.Add); | |
//Now we validate the AppShell.Items | |
foreach(var flyoutItem in Items) | |
{ | |
if (flyoutItem.Route.ToString().StartsWithIgnoreCase("Flyout")) ////By default, any item added without a Route starts with the Type (FlyoutItem, MenuItem, ShellItem, etc) | |
{ | |
Debug.WriteLine("Flyout Menu to Disable is: " + flyoutItem.Title); | |
flyoutItem.IsEnabled = false; ////This makes that particular flyout unclickable, so that you don't get a NULL crash | |
} | |
} | |
//Then you need a way to iterate through the list of created objects | |
//For my app, I'm using foreach and if/else to go through each item | |
foreach (var menuRemove in Items.ToList()) | |
{ | |
if (notAuth.Contains(menuRemove.Route.ToString())) ////notAuth is a list I built that is comparing Items.ToList() versus a list I generate from an API call where I get a list of Authorized functions | |
{ | |
if (menuRemove.Route.ToString() == "home") | |
{ | |
Debug.WriteLine("Shell Item is HOME... Leave in place"); ////This part of the code would need to be specific to your use case, use if/else, switch, foreach, etc --- but you'd have to play with it to see what works for you | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
puedes compartir en archivo xaml, gracias