Xamarin Forms Sidebar - xamarin

I have created a basic Master Detail navigation by following the following code:
https://developer.xamarin.com/guides/xamarin-forms/user-interface/navigation/master-detail-page/
I want to be able to make a clickable section on my sidebar which will take the user to their profile page. Similar to googles sidebar: https://github.com/jamesmontemagno/Xam.NavDrawer
Where can i find some tutorials on how i would do that? They would click on their name/profile picture and that would take them to their profile page.

Checkout SlideOverKit for Xamarin.Forms #
https://github.com/XAM-Consulting/SlideOverKit
It allows menu slide outs, sliding panels, etc... from the top, bottom, left, right...

Here is an example of navigating to another page on click of an image in MasterPage. This is the XAML of the Image in MasterPage.
<Image
x:Name="profileImage"
HeightRequest="100"
WidthRequest="100"
HorizontalOptions="Center"/>
We will add a TapGestureRecogniser to the Image and then invoke an Event defined in MasterPage.
public partial class MenuPage : ContentPage
{
public event EventHandler MenuTapped;
public MenuPage ()
{
InitializeComponent ();
TapGestureRecognizer imageViewTap = new TapGestureRecognizer ();
imageViewTap.Tapped+= ImageViewTap_Tapped;
profileImage.GestureRecognizers.Add (imageViewTap);
}
async void ImageViewTap_Tapped (object sender, EventArgs e)
{
if (MenuTapped != null)
MenuTapped (this,EventArgs.Empty);
}
}
We can listen to the event invoked from MasterPage in the MasterDetailPage and navigate to Profile page.
public class DashboardPage : MasterDetailPage
{
DetailPage detailPage;
MenuPage masterPage;
public DashboardPage ()
{
detailPage = new DetailPage ();
var detailNavigationPage=new NavigationPage(detailPage);
Detail = detailNavigationPage;
masterPage= new MenuPage(){Title="Menu",Icon="ic_menuIcon.png"};
Master = masterPage;
masterPage.MenuTapped+= MasterPage_MenuTapped;
}
async void MasterPage_MenuTapped (object sender, EventArgs e)
{
Detail=new new NavigationPage(new ProfilePage());// If you want to load profile page as `DetailPage`
await Navigation.PushModalAsync(new ProfilePage)// If you want to load profile page as another page modally.
}

Related

UI freezes for 2-3 seconds when loading a carouselview

I have a carouselview binded to a viewmodel, on the previous page (call it first page) user can select 2 arguments and with the help of those, the next view (call it second page) is generated accordingly. However, I can't wrap my head around why my view won't load asynchronously.
So my problem: When I click the button on the first page the UI would freeze for like a solid 2-3 seconds, and then start load (asynchronously?) and once it's done it's all good.
Also I couldn't really figure out a better way to inherit values from first page to second so if someone has an idea please let me know.
Any help on how can I fix this I would really appreciate.
The viewmodel for second page
public class DataSelectionViewModel : BaseViewModel
{
public ObservableCollection<Items> FilteredData { get; set; }
public UserSelectionViewModel()
{
_dataStore = DependencyService.Get<IDataStore>();
LoadData= new AsyncAwaitBestPractices.MVVM.AsyncCommand(FilterData);
FilteredData = new ObservableRangeCollection<Items>();
}
public async Task FilterData()
{
FilteredData.Clear();
var filtereddata = await _dataStore.SearchData(Hard, Subject).ConfigureAwait(false);
foreach (var data in filtereddata)
{
FilteredData.Add(data);
}
}
}
The carouselview in second page
<ContentPage.BindingContext>
<db:DataSelectionViewModel/>
</ContentPage.BindingContext>
...
<!-- DataTemplate for carouselview has radiobuttons, label and button all in a grid -->
<CarouselView ItemsSource="{Binding FilteredData}">
Second Page c#
public partial class SecondPage : ContentPage
{
public Coll(bool hard, string subject)
{
InitializeComponent();
var vm = (BaseViewModel)BindingContext;
vm.Hard = hard;
vm.Subject = subject;
/* had to set "hard" and "subject" here again, otherwise data won't load */
}
protected override async void OnAppearing()
{
var vm = (DataSelectionViewModel)BindingContext;
base.OnAppearing();
await vm.LoadData.ExecuteAsync().ConfigureAwait(false);
}
}
The first page view containing the button
<Button x:Name="Start" Pressed="ButtonClick"/>
First page c# --> Here I also tried doing it with a command and a pressed at the same time, because I couldn't come up with a way to save variables to second page viewmodel, that's why I use pressed here
private async void ButtonClick(object sender, EventArgs e)
{
var vm = (BaseViewModel)BindingContext;
vm.Hard = HardButtonSelected == Hard;
vm.Subject = vm.Subject.ToLower();
await Navigation.PushAsync(new SecondPage(vm.Hard, vm.Subject));
}
I have tried not using the OnAppearing method to get my data, but then it wouldn't bind to the page and it would not show, if I were to previously fill the ObservableCollection with my data and then load the page although I would love to be able to do this because it would allow me to create a loading popup also.

How do I close all pages after changing an item's data?

I have a doubt in Xamarin forms, I have an application that I would like after finishing the training, it closes all the training screens and only the main screen remains, today I got a cod that does this, but when I restart the app and I login,
when he closes the screens instead of going back to the main screen he goes back to the login, I'm not using masterpage, could that be it?
source:
private async void BtnVoltar_Clicked(object sender, EventArgs e)
{
int numModals = Application.Current.MainPage.Navigation.ModalStack.Count;
// Pop each modal in the stack
for (int currModal = 0; currModal < numModals; currModal++)
{
await Application.Current.MainPage.Navigation.PopModalAsync();
}
await Navigation.PushModalAsync(new TabbedPageMenu());
}
Image Link
https://imgur.com/pOVVYBu
Another doubt would be after updating the data of an item, if it is possible to close the two screens and update it on the main screen
image link2
https://imgur.com/ZpevVNg
You can use the method to navigate to the different pages instead of close the pages.
The code in xaml you can add the command to do the navigation.
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type views:targetpagename}"
The code in xaml.cs or viewmodel
public ICommand NavigateCommand { get; private set; }
public MainPage()
{
InitializeComponent();
NavigateCommand = new Command<Type>(
async (Type pageType) =>
{
Page page = (Page)Activator.CreateInstance(pageType);
await Navigation.PushAsync(page);
});
BindingContext = this;
}

Xamarin Android back button is not working

I had build a Multipager Xamarin App, but after second page Android back button and Navigation back button is not working.
I had tried Shell Backbuttonbehavior , but with this only Top Navigation back button is working
<Shell.BackButtonBehavior>
<BackButtonBehavior Command="{Binding BackCommand}" IconOverride="back.png" />
</Shell.BackButtonBehavior>
I had tried overriding OnAppearing and OnDisappearing to set Current and pervious navigation but that too is not triggering on thrid page
protected override void OnAppearing()
{
base.OnAppearing();
Shell.Current.Navigating += Current_Navigating;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
Shell.Current.Navigating -= Current_Navigating;
}
private async void Current_Navigating(object sender, ShellNavigatingEventArgs e)
{
if (Models.PatientPlannerData.moveNext == false)
{
Shell.Current.Navigating -= Current_Navigating;
await Shell.Current.GoToAsync("..", true);
}
}
For Navigation from one page to another I am using
await Shell.Current.GoToAsync(nameof(Page2));
Everything is working fine till second page, from third page back button is not triggering
For the Android back button, after compilation the Navigation Bar that we call in Xamarin Forms, turns into the Action Bar for Android during runtime.
Set the toolbar after LoadApplication(new App()); in OnCreate of MainActivity.
AndroidX.AppCompat.Widget.Toolbar toolbar
= this.FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
And then overrode OnOptionsItemSelected(). When you press the backbutton on navigation bar, this event would be triggered.
public override bool OnOptionsItemSelected(IMenuItem item)
{
}

Button x:Name="btnBack" not navigating to previous page

I am developing Xamarin Forms application for IOS and Android.I have the list of 3 xamarin form pages say X.xaml, Y.xaml, Z.xaml. Page X.xaml, Y.xaml is having 1 and click on that button it opens the next-next Xamarin form. And last on Z.xaml having 2 buttons btnBack & btnConfirm
<Button x:Name="btnBack"></Button>
<Button x:Name="btnConfirm"></Button>
when I click on that back button I want to navigate it to my previous page, but I don't want it like Navigation Back Button or Hardware Back Button click.
for this I have tried this code this will not work.
Z.xaml.cs
public partial class Z : ContentPage
{
public Z()
{
InitializeComponent();
btnBack.Clicked += btnBack_Clicked;
}
private void btnBack_Clicked(object sender, EventArgs e)
{
var existingPages = Navigation.NavigationStack.ToList();
foreach (var page in existingPages)
{
if(page == this)
Navigation.RemovePage(page);
}
}
}
In this code when I click on Back Button it Navigate me to prevoius page ie Y.xaml once I click on button which is on Y.xaml and open the Z.xaml page it shows me blank.
Y.xaml.cs
public partial class Y: ContentPage
{
public Y()
{
InitializeComponent();
btnZ.Clicked += btnZ_Clicked;
}
void btnZ_Clicked(object sender, System.EventArgs e)
{
Navigation.PushAsync(new Z());
}
}
#Kowalski had the right answer however it is incomplete.
You have to await Navigation.PopAsync() otherwise you may mess up the navigation stack. So always await it. Example:
async void btnBack_Clicked(object sender, EventArgs e)
{
await Navigation.PopAsync();
}
Beside that be aware that there are bugs in Xamarin.Forms related to navigation, here is one that might be interesting for you as well:
https://bugzilla.xamarin.com/show_bug.cgi?id=59172
P.S.: Here you can find the official guide on Popping Pages from the Navigation Stack.
you should invoke Navigation.PopAsync() to go back

Custom Popup in Xamarin.Forms

Is there any way to create custom popup dialog with Editor inside it using Xamarin Forms. Targeted to iOS platform.
I want a pop up with a Title Label ,Text box for accepting input and error Label for displaying error message, with OK and Cancel button.
I want to accept pin number from input pop up and have to validate pin. If validation fails I have to show a Error message inside pop up.
Thanks,
This is a good popup for XF that includes the ability to add an editor to the popup.
Popup Page Plugin for Xamarin Forms
// Use these methods in PopupNavigation globally or Navigation in your pages
// Open new PopupPage
Task PushAsync(PopupPage page, bool animate = true) // Navigation.PushPopupAsync
// Hide last PopupPage
Task PopAsync(bool animate = true) // Navigation.PopPopupAsync
// Hide all PopupPage with animations
Task PopAllAsync(bool animate = true) // Navigation.PopAllPopupAsync
// Remove one popup page in stack
Task RemovePageAsync(PopupPage page, bool animate = true) // Navigation.RemovePopupPageAsync
XAML POPUP PAGE
<?xml version="1.0" encoding="utf-8" ?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
x:Class="Demo.Pages.MyPopupPage">
<!--Animations use example-->
<pages:PopupPage.Animation>
<animations:ScaleAnimation
PositionIn="Center"
PositionOut="Center"
ScaleIn="1.2"
ScaleOut="0.8"
DurationIn="400"
DurationOut="300"
EasingIn="SinOut"
EasingOut="SinIn"
HasBackgroundAnimation="True"/>
</pages:PopupPage.Animation>
<!-- Content -->
</pages:PopupPage>
POPUP PAGE
public partial class MyPopupPage : PopupPage
{
public SecondPopupPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
}
protected override void OnDisappearing()
{
base.OnDisappearing();
}
// Method for animation child in PopupPage
// Invoced after custom animation end
protected virtual Task OnAppearingAnimationEnd()
{
return Content.FadeTo(0.5);
}
// Method for animation child in PopupPage
// Invoked before custom animation begin
protected virtual Task OnDisappearingAnimationBegin()
{
return Content.FadeTo(1);;
}
protected override bool OnBackButtonPressed()
{
// Prevent hide popup
//return base.OnBackButtonPressed();
return true;
}
// Invoced when background is clicked
protected override bool OnBackgroundClicked()
{
// Return default value - CloseWhenBackgroundIsClicked
return base.OnBackgroundClicked();
}
}
MAINPAGE
// Main Page
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
// Button Click
private async void OnOpenPupup(object sender, EventArgs e)
{
var page = new MyPopupPage();
await Navigation.PushPopupAsync(page);
// or
await PopupNavigation.PushAsync(page);
}
}
Have a look at ACR User Dialogs. https://github.com/aritchie/userdialogs
Nuget Package: https://www.nuget.org/packages/Acr.UserDialogs/
Then have a look at the Prompt Examples: https://github.com/aritchie/userdialogs/blob/master/src/Samples/Samples/ViewModels/StandardViewModel.cs#L97
void Prompt()
{
UserDialogs.Instance.ActionSheet(new ActionSheetConfig()
.SetTitle("Choose Type")
.Add("Default", () => this.PromptCommand(InputType.Default))
.Add("E-Mail", () => this.PromptCommand(InputType.Email))
.Add("Name", () => this.PromptCommand(InputType.Name))
.Add("Number", () => this.PromptCommand(InputType.Number))
.Add("Number with Decimal", () => this.PromptCommand(InputType.DecimalNumber))
.Add("Password", () => this.PromptCommand(InputType.Password))
.Add("Numeric Password (PIN)", () => this.PromptCommand(InputType.NumericPassword))
.Add("Phone", () => this.PromptCommand(InputType.Phone))
.Add("Url", () => this.PromptCommand(InputType.Url))
);
}
Yes, a custom popup can be added in Xamarin forms. Please follow these steps:
Create one stacklayout.
Add the fields in to the stacklayout.
Create one new Frame object.
Make the Frame object background with transaprent color.
Add the Stacklayout object into frame.
Add the frame to main content page.
If you need code, I will update.

Resources