Okay, let's see if I can do this now that I have my heart set on it LOL.
In my app, I want to let the user select what options will appear on the main menu. I am using the Master Detail template project from VisualStudio, so the basic menu is built like so.
App constructor (entrypoint ish)
public App() { InitializeComponent(); DependencyService.Register<MockDataStore>(); MainPage = new MainPage(); //Build the main page and populate the menu. }
This is where we construct the main page, and it's components so hence where the menu gets generated. My fear here, is that this also means it's a fire and forget/"you no touch this" type component...
public partial class MainPage : MasterDetailPage { Dictionary<int, NavigationPage> MenuPages = new Dictionary<int, NavigationPage>(); public MainPage() { InitializeComponent(); MasterBehavior = MasterBehavior.Popover; MenuPages.Add((int)MenuItemType.Browse, (NavigationPage)Detail); } public async Task NavigateFromMenu(int id) { if (!MenuPages.ContainsKey(id)) { switch (id) { case (int)MenuItemType.Browse: MenuPages.Add(id, new NavigationPage(new ItemsPage())); break; case (int)MenuItemType.About: MenuPages.Add(id, new NavigationPage(new AboutPage())); break; } } var newPage = MenuPages[id]; if (newPage != null && Detail != newPage) { Detail = newPage; if (Device.RuntimePlatform == Device.Android) await Task.Delay(100); IsPresented = false; }
Now we are down to the proverbial meat and potatoes, this has been updated with some of the code I am using, just in a generalized way
public partial class MenuPage : ContentPage { MainPage RootPage { get => Application.Current.MainPage as MainPage; } List<HomeMenuItem> menuItems; public MenuPage() { InitializeComponent(); menuItems = new List<HomeMenuItem> { new HomeMenuItem {Id = MenuItemType.Browse, Title="Browse", Visible=Preferences.Get("Browse", false);}, new HomeMenuItem {Id = MenuItemType.About, Title="About", Visible=Preferences.Get("Browse", false); } new HomeMenuItem {Id = MenuItemType.YouGetMyPoint, Title="YouGetMyPoint", Visible=Preferences.Get("YouGetMyPoint", false); } }; ListViewMenu.ItemsSource = menuItems; ListViewMenu.SelectedItem = menuItems[0]; ListViewMenu.ItemSelected += async (sender, e) => { if (e.SelectedItem == null) return; var id = (int)((HomeMenuItem)e.SelectedItem).Id; await RootPage.NavigateFromMenu(id); }; } }
Then in the handy MenuPage.cs.xaml
<ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid Padding="10"> <StackLayout isVisible="{Binding Path=Visible}"> <Label Text="{Binding Title}" d:Text="{Binding .}" FontSize="20"/> </StackLayout> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate>
This is code in a settings page used to configure the app behavior and so on...
cbBrowse.IsChecked = Preferences.Get("Browse", false); cbBrowse.StateChanged += (s, e) => Preferences.Set("Browse", Convert.ToBoolean(e.IsChecked)); cbAbout.IsChecked Preferences.Get("About", false); cbAbout.StateChanged += (s, e) => Preferences.Set("About", Convert.ToBoolean(e.IsChecked)); cbYouGetMyPoint.IsChecked = Preferences.Get("YouGetMyPoint", false); cbYouGetMyPoint.StateChanged += (s, e) => Preferences.Set("YouGetMyPoint", Convert.ToBoolean(e.IsChecked));
The problem I have, while this does work, it only works once the user closes the app and opens it again...
Is there a way for me to force the menu to process the MenuPage class again? Since it's embeded into the MainPage that seems an awful like trying to refresh the whole app which seems cumbersome to just change a flag on a single stack layout...
Anyhow any assistance or guidance would be most appreciated!