Hide Navigation Bar on MasterDetailPage - xamarin

I have a MasterDetailPage that contains the following constructor:
public MainPage()
{
NavigationPage.SetHasNavigationBar(this, false);
NavigationPage.SetHasBackButton(this, false);
InitializeComponent();
MessagingCenter.Subscribe<JobsPage>(this, "OpenMenu", (sender) => {
IsPresented = true;
});
MasterPage.ListView.ItemSelected += ListView_ItemSelected;
this.MasterBehavior = MasterBehavior.Popover;
App.NavPage = new NavigationPage(new JobsPage() { Title = "Jobs" });
Detail = App.NavPage;
}
As you can see, I've set SetHasNavigationBar and SetHasBackButton to false.
On a different page (a ContentPage, not a MasterDetailPage), I did the same thing in the constructor:
NavigationPage.SetHasNavigationBar(this, false);
NavigationPage.SetHasBackButton(this, false);
InitializeComponent();
On my ContentPage, this works fine, as shown below.
On my MasterDetailPage, however, I'm still seeing the Navigation bar.
How can I fix this?

Not sure how is structured your navigation, but try this:
public MainPage()
{
InitializeComponent();
MessagingCenter.Subscribe<JobsPage>(this, "OpenMenu", (sender) => {
IsPresented = true;
});
MasterPage.ListView.ItemSelected += ListView_ItemSelected;
this.MasterBehavior = MasterBehavior.Popover;
var navPage = new NavigationPage(new JobsPage() { Title = "Jobs" });
NavigationPage.SetHasNavigationBar(navPage, false);
NavigationPage.SetHasBackButton(navPage, false);
App.NavPage = navPage;
Detail = App.NavPage;
}

As far as I know, a Master-DetailPage does not support Navigation Bars. It is the root container where you can place your content pages. These pages can now contain a navigation bar that can redirect you to the root page in the Master-DetailPage.

I faced similar issue and i had a work-around for this.
Set the Detail twice.
// 1st time
var jobPage = new JobsPage() { Title = "Jobs" };
Detail = jobPage;
// 2nd time
var navPage = new NavigationPage(jobPage, false);
Detail = navPage;
Set the 1st in constructor and 2nd in OnAppearing.
Try it.

Try setting those lines in detail page of the MasterDetailPage
In code behind
NavigationPage.SetHasNavigationBar(this, false);
In xaml
NavigationPage.HasNavigationBar="False"

Related

Unable to Navigate pages while keeping the tab bar accessible in xamarin forms

So I have a tab bar and some pages attached to it, and what I'm trying to do is navigate to a different page(not a tab bar page) by clicking a button which is present in one of these tab bar pages, on doing so that page is replacing the tab bar, how would I be able to navigate inside the tab bar itself, I checked a couple of threads and doing a PushAsync should do the trick but its not working
This is a snippet of my NavigateAsync Method
public async Task NavigateAsync(string pageKey, object[] parameter, bool animated = true)
{
var page = GetPage(pageKey, parameter);
await CurrentNavigationPage.Navigation.PushAsync(page, animated);
}
private readonly Stack<NavigationPage> _navigationPageStack = new Stack<NavigationPage>();
private NavigationPage CurrentNavigationPage => _navigationPageStack.Peek();
We have a CurrentPage property in TabbedPage. You will need this CurrentPage.Navigation object to push the page inside tab bar itself.
So it turns out in my navigation service, i was using the tabbedpage as a navigationpage to navigate to other pages, but if you get the current page (which should be encapsulated in a navigation while adding them as children to your tabbedpage), then using that if you navigate it creates a new page inside the current page instead of the whole tabbedpage
Here's my syntax for storing the currentPage as my navigation element to navigate
public Page SetRootPage(string rootPageKey = null, Page pageName = null)
{
NavigationPage tempPage = null;
if (rootPageKey != null)
{
var rootPage = GetPage(rootPageKey);
if (rootPage is TabbedPage tabbedRootPage)
{
tempPage = tabbedRootPage.CurrentPage as NavigationPage;
}
if (tempPage == null)
{
CurrentNavigationPage = rootPage is NavigationPage ? (NavigationPage)rootPage : new NavigationPage(rootPage);
}
else
{
CurrentNavigationPage = tempPage;
}
return CurrentNavigationPage;
// as NavigationPage;
//_navigationPageStack.Clear();
//var mainPage = new NavigationPage(rootPage);
// _navigationPageStack.Push(mainPage);
}
else
{
if (pageName is TabbedPage tabbedPage)
{
CurrentNavigationPage = tabbedPage.CurrentPage as NavigationPage;
}
else
{
CurrentNavigationPage = pageName as NavigationPage;
}
return CurrentNavigationPage;
}
}

Navigating from TabbedPage to ContentPage

I have a TabbedPage with three tabs which is my main page. In one of the tabs I have a ListView and on clicking on the Item in ListView I want to navigate to a new Page.
I can navigate to the new page but the page is displayed within the tab. I do not want the page to be within the tab and should take be opened a new page taking the whole screen.
This is my listView itemSelected method within one of the tabs.
How can I make the DocketDetail page take the entire screen.
I have tried making it the 'MainPage' which
App.Current.MainPage = new NavigationPage(new DocketDetail());
But doing this I could not go back to the TabbedPage.
Please suggest
lvLiveDockets.ItemSelected += (object sender, SelectedItemChangedEventArgs e) =>
{
if (e.SelectedItem == null)
{
DisplayAlert("Item DeSelected", e.SelectedItem.ToString(), "Ok");
return; //ItemSelected is called on deselection, which results in SelectedItem being set to null
}
else
{
DisplayAlert("Item Selected", e.SelectedItem.ToString(), "Ok");
this.Navigation.PushAsync(new DocketDetail());
}
//((ListView)sender).SelectedItem = null; //uncomment line if you want to disable the visual selection state.
};
My App.Xaml.cs
MainPage = new TabbedPage
{
Children =
{
new NavigationPage(new PendingDockets())
{
Title = "Pending Dockets",
Icon = Device.OnPlatform<string>("tab_about.png",null,null)
},
new NavigationPage(new LiveDockets())
{
Title = "Live Dockets",
Icon = Device.OnPlatform<string>("tab_about.png",null,null)
},
new NavigationPage(new ArchiveDockets())
{
Title = "Archive Dockets",
Icon = Device.OnPlatform<string>("tab_about.png",null,null)
},
}
};`
Your App.cs could be changed to this:
MainPage = new NavigationPage(new TabbedPage()
{
Children =
{
new PendingDockets()
{
Title = "Pending Dockets",
Icon = Device.OnPlatform<string>("tab_about.png",null,null)
},
new LiveDockets()
{
Title = "Live Dockets",
Icon = Device.OnPlatform<string>("tab_about.png",null,null)
},
new ArchiveDockets()
{
Title = "Archive Dockets",
Icon = Device.OnPlatform<string>("tab_about.png",null,null)
},
}
});
You have to put the TabbedPage inside a Navigation Stack (I think as Root page)
Application.Current.MainPage = new NavigationPage(new Tabpage());
when you select yout item in listview, you should push a new page
Navigation.PushAsync(new DocketDetail());
I hope to have understand your problem
lvLiveDockets.ItemSelected += (object sender, SelectedItemChangedEventArgs e) =>
{
if (e.SelectedItem == null)
{
DisplayAlert("Item DeSelected", e.SelectedItem.ToString(), "Ok");
return; //ItemSelected is called on deselection, which results in SelectedItem being set to null
}
else
{
DisplayAlert("Item Selected", e.SelectedItem.ToString(), "Ok");
Application.Current.MainPage = new DocketDetail();
}
//((ListView)sender).SelectedItem = null; //uncomment line if you want to disable the visual selection state.
};

In a TabbedPage, how can I push another Page over the current subpage?

(Complete code example is available here:
https://github.com/csvan/TabbedPageModalDemo)
I have the following page structure in my Xamarin.Forms app:
namespace TabbedPageModalDemo
{
public class MyTabbedPage : TabbedPage
{
public MyTabbedPage ()
{
Title = "Tabbed Page";
Children.Add (new MyTabPage ());
}
}
}
namespace TabbedPageModalDemo
{
public class MyTabPage : ContentPage
{
public MyTabPage ()
{
Title = "Tab Page";
var button = new Button {
Text = "Open Modal"
};
// Using PushModal as an example - PushAsync also fills the whole screen.
button.Clicked += (sender, e) => Navigation.PushModalAsync (new MyModalPage ());
var stack = new StackLayout ();
stack.Children.Add (button);
Content = stack;
}
}
}
namespace TabbedPageModalDemo
{
public class MyModalPage : ContentPage
{
public MyModalPage ()
{
Title = "Modal Page";
var label = new Label {
Text = "I am a modal page!"
};
var stack = new StackLayout ();
stack.Children.Add (label);
Content = stack;
}
}
}
What I want is the following: when I press the button, I would like MyModalPage to only take up the same space that is occupied by MyTabPage. Currently, it fills the entire screen, covering MyTabbedPage as well. Note that the same happens if I use PushAsync instead.
How can I resolve this?
Did you try used padding inside your current modal page?
Padding = new Thickness(0,30,0,0);
I think the better approach would be to use NavigationPages instead of a ContentPage as your Child-Elements. A good example can be seen here.

How do you switch pages in Xamarin.Forms?

How do you switch between pages in Xamarin Forms?
My main page is a ContentPage and I don't want to switch to something like a Tabbed Page.
I've been able to pseudo-do it by finding parents of the controls that should trigger the new page until I find the ContentPage and then swap out the Content with controls for a new page. But this seems really sloppy.
In the App class you can set the MainPage to a Navigation Page and set the root page to your ContentPage:
public App ()
{
// The root page of your application
MainPage = new NavigationPage( new FirstContentPage() );
}
Then in your first ContentPage call:
Navigation.PushAsync (new SecondContentPage ());
Xamarin.Forms supports multiple navigation hosts built-in:
NavigationPage, where the next page slide in,
TabbedPage, the one you don't like
CarouselPage, that allows for switching left and right to next/prev pages.
On top of this, all pages also supports PushModalAsync() which just push a new page on top of the existing one.
At the very end, if you want to make sure the user can't get back to the previous page (using a gesture or the back hardware button), you can keep the same Page displayed and replace its Content.
The suggested options of replacing the root page works as well, but you'll have to handle that differently for each platform.
If your project has been set up as a PCL forms project (and very likely as Shared Forms as well but I haven't tried that) there is a class App.cs that looks like this:
public class App
{
public static Page GetMainPage ()
{
AuditorDB.Model.Extensions.AutoTimestamp = true;
return new NavigationPage (new LoginPage ());
}
}
you can modify the GetMainPage method to return a new TabbedPaged or some other page you have defined in the project
From there on you can add commands or event handlers to execute code and do
// to show OtherPage and be able to go back
Navigation.PushAsync(new OtherPage());
// to show AnotherPage and not have a Back button
Navigation.PushModalAsync(new AnotherPage());
// to go back one step on the navigation stack
Navigation.PopAsync();
Push a new page onto the stack, then remove the current page. This results in a switch.
item.Tapped += async (sender, e) => {
await Navigation.PushAsync (new SecondPage ());
Navigation.RemovePage(this);
};
You need to be in a Navigation Page first:
MainPage = NavigationPage(new FirstPage());
Switching content isn't ideal as you have just one big page and one set of page events like OnAppearing ect.
If you do not want to go the previous page i.e. do not let the user go back to the login screen once authorization is done, then you can use;
App.Current.MainPage = new HomePage();
If you want to enable back functionality, just use
Navigation.PushModalAsync(new HomePage())
Seems like this thread is very popular and it will be sad not to mention here that there is an alternative way - ViewModel First Navigation. Most of the MVVM frameworks out there using it, however if you want to understand what it is about, continue reading.
All the official Xamarin.Forms documentation is demonstrating a simple, yet slightly not MVVM pure solution. That is because the Page(View) should know nothing about the ViewModel and vice versa. Here is a great example of this violation:
// C# version
public partial class MyPage : ContentPage
{
public MyPage()
{
InitializeComponent();
// Violation
this.BindingContext = new MyViewModel();
}
}
// XAML version
<?xml version="1.0" encoding="utf-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:MyApp.ViewModel"
x:Class="MyApp.Views.MyPage">
<ContentPage.BindingContext>
<!-- Violation -->
<viewmodels:MyViewModel />
</ContentPage.BindingContext>
</ContentPage>
If you have a 2 pages application this approach might be good for you. However if you are working on a big enterprise solution you better go with a ViewModel First Navigation approach. It is slightly more complicated but much cleaner approach that allow you to navigate between ViewModels instead of navigation between Pages(Views). One of the advantages beside clear separation of concerns is that you could easily pass parameters to the next ViewModel or execute an async initialization code right after navigation. Now to details.
(I will try to simplify all the code examples as much as possible).
1. First of all we need a place where we could register all our objects and optionally define their lifetime. For this matter we can use an IOC container, you can choose one yourself. In this example I will use Autofac(it is one of the fastest available). We can keep a reference to it in the App so it will be available globally (not a good idea, but needed for simplification):
public class DependencyResolver
{
static IContainer container;
public DependencyResolver(params Module[] modules)
{
var builder = new ContainerBuilder();
if (modules != null)
foreach (var module in modules)
builder.RegisterModule(module);
container = builder.Build();
}
public T Resolve<T>() => container.Resolve<T>();
public object Resolve(Type type) => container.Resolve(type);
}
public partial class App : Application
{
public DependencyResolver DependencyResolver { get; }
// Pass here platform specific dependencies
public App(Module platformIocModule)
{
InitializeComponent();
DependencyResolver = new DependencyResolver(platformIocModule, new IocModule());
MainPage = new WelcomeView();
}
/* The rest of the code ... */
}
2.We will need an object responsible for retrieving a Page (View) for a specific ViewModel and vice versa. The second case might be useful in case of setting the root/main page of the app. For that we should agree on a simple convention that all the ViewModels should be in ViewModels directory and Pages(Views) should be in the Views directory. In other words ViewModels should live in [MyApp].ViewModels namespace and Pages(Views) in [MyApp].Views namespace. In addition to that we should agree that WelcomeView(Page) should have a WelcomeViewModel and etc. Here is a code example of a mapper:
public class TypeMapperService
{
public Type MapViewModelToView(Type viewModelType)
{
var viewName = viewModelType.FullName.Replace("Model", string.Empty);
var viewAssemblyName = GetTypeAssemblyName(viewModelType);
var viewTypeName = GenerateTypeName("{0}, {1}", viewName, viewAssemblyName);
return Type.GetType(viewTypeName);
}
public Type MapViewToViewModel(Type viewType)
{
var viewModelName = viewType.FullName.Replace(".Views.", ".ViewModels.");
var viewModelAssemblyName = GetTypeAssemblyName(viewType);
var viewTypeModelName = GenerateTypeName("{0}Model, {1}", viewModelName, viewModelAssemblyName);
return Type.GetType(viewTypeModelName);
}
string GetTypeAssemblyName(Type type) => type.GetTypeInfo().Assembly.FullName;
string GenerateTypeName(string format, string typeName, string assemblyName) =>
string.Format(CultureInfo.InvariantCulture, format, typeName, assemblyName);
}
3.For the case of setting a root page we will need sort of ViewModelLocator that will set the BindingContext automatically:
public static class ViewModelLocator
{
public static readonly BindableProperty AutoWireViewModelProperty =
BindableProperty.CreateAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocator), default(bool), propertyChanged: OnAutoWireViewModelChanged);
public static bool GetAutoWireViewModel(BindableObject bindable) =>
(bool)bindable.GetValue(AutoWireViewModelProperty);
public static void SetAutoWireViewModel(BindableObject bindable, bool value) =>
bindable.SetValue(AutoWireViewModelProperty, value);
static ITypeMapperService mapper = (Application.Current as App).DependencyResolver.Resolve<ITypeMapperService>();
static void OnAutoWireViewModelChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as Element;
var viewType = view.GetType();
var viewModelType = mapper.MapViewToViewModel(viewType);
var viewModel = (Application.Current as App).DependencyResolver.Resolve(viewModelType);
view.BindingContext = viewModel;
}
}
// Usage example
<?xml version="1.0" encoding="utf-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:MyApp.ViewModel"
viewmodels:ViewModelLocator.AutoWireViewModel="true"
x:Class="MyApp.Views.MyPage">
</ContentPage>
4.Finally we will need a NavigationService that will support ViewModel First Navigation approach:
public class NavigationService
{
TypeMapperService mapperService { get; }
public NavigationService(TypeMapperService mapperService)
{
this.mapperService = mapperService;
}
protected Page CreatePage(Type viewModelType)
{
Type pageType = mapperService.MapViewModelToView(viewModelType);
if (pageType == null)
{
throw new Exception($"Cannot locate page type for {viewModelType}");
}
return Activator.CreateInstance(pageType) as Page;
}
protected Page GetCurrentPage()
{
var mainPage = Application.Current.MainPage;
if (mainPage is MasterDetailPage)
{
return ((MasterDetailPage)mainPage).Detail;
}
// TabbedPage : MultiPage<Page>
// CarouselPage : MultiPage<ContentPage>
if (mainPage is TabbedPage || mainPage is CarouselPage)
{
return ((MultiPage<Page>)mainPage).CurrentPage;
}
return mainPage;
}
public Task PushAsync(Page page, bool animated = true)
{
var navigationPage = Application.Current.MainPage as NavigationPage;
return navigationPage.PushAsync(page, animated);
}
public Task PopAsync(bool animated = true)
{
var mainPage = Application.Current.MainPage as NavigationPage;
return mainPage.Navigation.PopAsync(animated);
}
public Task PushModalAsync<TViewModel>(object parameter = null, bool animated = true) where TViewModel : BaseViewModel =>
InternalPushModalAsync(typeof(TViewModel), animated, parameter);
public Task PopModalAsync(bool animated = true)
{
var mainPage = GetCurrentPage();
if (mainPage != null)
return mainPage.Navigation.PopModalAsync(animated);
throw new Exception("Current page is null.");
}
async Task InternalPushModalAsync(Type viewModelType, bool animated, object parameter)
{
var page = CreatePage(viewModelType);
var currentNavigationPage = GetCurrentPage();
if (currentNavigationPage != null)
{
await currentNavigationPage.Navigation.PushModalAsync(page, animated);
}
else
{
throw new Exception("Current page is null.");
}
await (page.BindingContext as BaseViewModel).InitializeAsync(parameter);
}
}
As you may see there is a BaseViewModel - abstract base class for all the ViewModels where you can define methods like InitializeAsync that will get executed right after the navigation. And here is an example of navigation:
public class WelcomeViewModel : BaseViewModel
{
public ICommand NewGameCmd { get; }
public ICommand TopScoreCmd { get; }
public ICommand AboutCmd { get; }
public WelcomeViewModel(INavigationService navigation) : base(navigation)
{
NewGameCmd = new Command(async () => await Navigation.PushModalAsync<GameViewModel>());
TopScoreCmd = new Command(async () => await navigation.PushModalAsync<TopScoreViewModel>());
AboutCmd = new Command(async () => await navigation.PushModalAsync<AboutViewModel>());
}
}
As you understand this approach is more complicated, harder to debug and might be confusing. However there are many advantages plus you actually don't have to implement it yourself since most of the MVVM frameworks support it out of the box. The code example that is demonstrated here is available on github. There are plenty of good articles about ViewModel First Navigation approach and there is a free Enterprise Application Patterns using Xamarin.Forms eBook which is explaining this and many other interesting topics in detail.
By using the PushAsync() method you can push and PopModalAsync() you can pop pages to and from the navigation stack. In my code example below I have a Navigation page (Root Page) and from this page I push a content page that is a login page once I am complete with my login page I pop back to the root page
~~~ Navigation can be thought of as a last-in, first-out stack of Page objects.To move from one page to another an application will push a new page onto this stack. To return back to the previous page the application will pop the current page from the stack. This navigation in Xamarin.Forms is handled by the INavigation interface
Xamarin.Forms has a NavigationPage class that implements this interface and will manage the stack of Pages. The NavigationPage class will also add a navigation bar to the top of the screen that displays a title and will also have a platform appropriate Back button that will return to the previous page. The following code shows how to wrap a NavigationPage around the first page in an application:
Reference to content listed above and a link you should review for more information on Xamarin Forms, see the Navigation section:
http://developer.xamarin.com/guides/cross-platform/xamarin-forms/introduction-to-xamarin-forms/
~~~
public class MainActivity : AndroidActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
// Set our view from the "main" layout resource
SetPage(BuildView());
}
static Page BuildView()
{
var mainNav = new NavigationPage(new RootPage());
return mainNav;
}
}
public class RootPage : ContentPage
{
async void ShowLoginDialog()
{
var page = new LoginPage();
await Navigation.PushModalAsync(page);
}
}
//Removed code for simplicity only the pop is displayed
private async void AuthenticationResult(bool isValid)
{
await navigation.PopModalAsync();
}
In App.Xaml.Cs:
MainPage = new NavigationPage( new YourPage());
When you wish to navigate from YourPage to the next page you do:
await Navigation.PushAsync(new YourSecondPage());
You can read more about Xamarin Forms navigation here: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/navigation/hierarchical
Microsoft has quite good docs on this.
There is also the newer concept of the Shell. It allows for a new way of structuring your application and simplifies navigation in some cases.
Intro: https://devblogs.microsoft.com/xamarin/shell-xamarin-forms-4-0-getting-started/
Video on basics of Shell: https://www.youtube.com/watch?v=0y1bUAcOjZY&t=3112s
Docs: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/
Call:
((App)App.Current).ChangeScreen(new Map());
Create this method inside App.xaml.cs:
public void ChangeScreen(Page page)
{
MainPage = page;
}
In Xamarin we have page called NavigationPage. It holds stack of ContentPages.
NavigationPage has method like PushAsync() and PopAsync(). PushAsync add a page at the top of the stack, at that time that page will become the currently active page. PopAsync() method remove the page from the top of the stack.
In App.Xaml.Cs set like.
MainPage = new NavigationPage( new YourPage());
From YourPage you await Navigation.PushAsync(new newPage()); this method will add newPage at the top of the stack. At this time newPage will be currently active page.
One page to another page navigation in Xamarin.forms using Navigation property Below sample code
void addClicked(object sender, EventArgs e)
{
//var createEmp = (Employee)BindingContext;
Employee emp = new Employee();
emp.Address = AddressEntry.Text;
App.Database.SaveItem(emp);
this.Navigation.PushAsync(new EmployeeDetails());
this.Navigation.PushModalAsync(new EmployeeDetails());
}
To navigate one page to another page with in view cell Below code Xamrian.forms
private async void BtnEdit_Clicked1(object sender, EventArgs e)
{
App.Database.GetItem(empid);
await App.Current.MainPage.Navigation.PushModalAsync(new EmployeeRegistration(empid));
}
Example like below
public class OptionsViewCell : ViewCell
{
int empid;
Button btnEdit;
public OptionsViewCell()
{
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (this.BindingContext == null)
return;
dynamic obj = BindingContext;
empid = Convert.ToInt32(obj.Eid);
var lblname = new Label
{
BackgroundColor = Color.Lime,
Text = obj.Ename,
};
var lblAddress = new Label
{
BackgroundColor = Color.Yellow,
Text = obj.Address,
};
var lblphonenumber = new Label
{
BackgroundColor = Color.Pink,
Text = obj.phonenumber,
};
var lblemail = new Label
{
BackgroundColor = Color.Purple,
Text = obj.email,
};
var lbleid = new Label
{
BackgroundColor = Color.Silver,
Text = (empid).ToString(),
};
//var lbleid = new Label
//{
// BackgroundColor = Color.Silver,
// // HorizontalOptions = LayoutOptions.CenterAndExpand
//};
//lbleid.SetBinding(Label.TextProperty, "Eid");
Button btnDelete = new Button
{
BackgroundColor = Color.Gray,
Text = "Delete",
//WidthRequest = 15,
//HeightRequest = 20,
TextColor = Color.Red,
HorizontalOptions = LayoutOptions.EndAndExpand,
};
btnDelete.Clicked += BtnDelete_Clicked;
//btnDelete.PropertyChanged += BtnDelete_PropertyChanged;
btnEdit = new Button
{
BackgroundColor = Color.Gray,
Text = "Edit",
TextColor = Color.Green,
};
// lbleid.SetBinding(Label.TextProperty, "Eid");
btnEdit.Clicked += BtnEdit_Clicked1; ;
//btnEdit.Clicked += async (s, e) =>{
// await App.Current.MainPage.Navigation.PushModalAsync(new EmployeeRegistration());
//};
View = new StackLayout()
{
Orientation = StackOrientation.Horizontal,
BackgroundColor = Color.White,
Children = { lbleid, lblname, lblAddress, lblemail, lblphonenumber, btnDelete, btnEdit },
};
}
private async void BtnEdit_Clicked1(object sender, EventArgs e)
{
App.Database.GetItem(empid);
await App.Current.MainPage.Navigation.PushModalAsync(new EmployeeRegistration(empid));
}
private void BtnDelete_Clicked(object sender, EventArgs e)
{
// var eid = Convert.ToInt32(empid);
// var item = (Xamarin.Forms.Button)sender;
int eid = empid;
App.Database.DeleteItem(empid);
}
}
After PushAsync use PopAsync (with this) to remove current page.
await Navigation.PushAsync(new YourSecondPage());
this.Navigation.PopAsync(this);
XAML page add this
<ContentPage.ToolbarItems>
<ToolbarItem Text="Next" Order="Primary"
Activated="Handle_Activated"/>
</ContentPage.ToolbarItems>
on the CS page
async void Handle_Activated(object sender, System.EventArgs e)
{
await App.Navigator.PushAsync(new PAGE());
}

How can I create a drawer / slider menu with Xamarin.Forms?

How do I create an a slider menu using Xamarin.Forms? Is it baked in or something custom?
You create a new class which contains all the definitions for both the Master - i.e. the menu - and the Detail - i.e. the main page. I know, it sounds back-to-front, but for example..
using System;
using Xamarin.Forms;
namespace testXamForms
{
public class HomePage : MasterDetailPage
{
public HomePage()
{
// Set up the Master, i.e. the Menu
Label header = new Label
{
Text = "MENU",
Font = Font.BoldSystemFontOfSize(20),
HorizontalOptions = LayoutOptions.Center
};
// create an array of the Page names
string[] myPageNames = {
“Main”,
“Page 2”,
“Page 3”,
};
// Create ListView for the Master page.
ListView listView = new ListView
{
ItemsSource = myPageNames,
};
// The Master page is actually the Menu page for us
this.Master = new ContentPage
{
Title = "The Title is required.",
Content = new StackLayout
{
Children =
{
header,
listView
},
}
};
// Define a selected handler for the ListView contained in the Master (ie Menu) Page.
listView.ItemSelected += (sender, args) =>
{
// Set the BindingContext of the detail page.
this.Detail.BindingContext = args.SelectedItem;
Console.WriteLine("The args.SelectedItem is
{0}",args.SelectedItem);
// This is where you would put your “go to one of the selected pages”
// Show the detail page.
this.IsPresented = false;
};
// Set up the Detail, i.e the Home or Main page.
Label myHomeHeader = new Label
{
Text = "Home Page",
HorizontalOptions = LayoutOptions.Center
};
string[] homePageItems = { “Alpha”, “Beta”, “Gamma” };
ListView myHomeView = new ListView {
ItemsSource = homePageItems,
};
var myHomePage = new ContentPage();
myHomePage.Content = new StackLayout
{
Children =
{
myHomeHeader,
myHomeView
} ,
};
this.Detail = myHomePage;
}
}
}
It is built in: MasterDetailPage. You'd set the Detail and Master properties of it to whatever kinds of Pages you'd like. I found Hansleman.Forms to be quite enlightening.
My minimum example (as posted here) is as follows:
public class App
{
static MasterDetailPage MDPage;
public static Page GetMainPage()
{
return MDPage = new MasterDetailPage {
Master = new ContentPage {
Title = "Master",
BackgroundColor = Color.Silver,
Icon = Device.OS == TargetPlatform.iOS ? "menu.png" : null,
Content = new StackLayout {
Padding = new Thickness(5, 50),
Children = { Link("A"), Link("B"), Link("C") }
},
},
Detail = new NavigationPage(new ContentPage {
Title = "A",
Content = new Label { Text = "A" }
}),
};
}
static Button Link(string name)
{
var button = new Button {
Text = name,
BackgroundColor = Color.FromRgb(0.9, 0.9, 0.9)
};
button.Clicked += delegate {
MDPage.Detail = new NavigationPage(new ContentPage {
Title = name,
Content = new Label { Text = name }
});
MDPage.IsPresented = false;
};
return button;
}
}
An example solution is hosted on GitHub.
On iOS the result looks like this (left: menu open, right: after clicking on "B"):
Note that you need to add the menu icon as a resource in your iOS project.
If you are looking for simple example of MasterDetailPage please have a look at my sample repo at GitHub. Very nice example is also presented here
Slideoverkit is a great plugin available for Xamarin Forms. There is a github to see free samples and you could find documentation about it here.

Resources