Skip to content

Instantly share code, notes, and snippets.

@TheBaileyBrew
Created June 5, 2019 19:40
Show Gist options
  • Save TheBaileyBrew/f8a9d2e4668da3ec9bff9bf86d32d951 to your computer and use it in GitHub Desktop.
Save TheBaileyBrew/f8a9d2e4668da3ec9bff9bf86d32d951 to your computer and use it in GitHub Desktop.
Creating FlyoutItems Dynamically in Xamarin.Forms Shell
//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
}
}
}
@eincioch
Copy link

puedes compartir en archivo xaml, gracias

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment