handle tap event in the whole content page out of certain element - xamarin.forms

after i finished slide down menu (which is a stacklayout containing buttons) on button click on my Pcl i am trying to hide this menu when the user taps any part of the page out of my menu
i used TapGestureRecongnizer and added it to content but it doesnot work on other children elements
TapGestureRecognizer ContentGesture = new TapGestureRecognizer();
ContentGesture.Tapped +=(s,o)=>{
if (CornerFrame.IsVisible == true)
{ CornerFrame.IsVisible = false; }
};
this.Content.GestureRecognizers.Add(ContentGesture);

Try this
Below code in your stack layout page
public event EventHandler<bool> ItemChanged;
TapGestureRecognizer ContentGesture = new TapGestureRecognizer();
ContentGesture.Tapped +=(s,o)=>{
ItemChanged?.Invoke(this, true);
};
this.Content.GestureRecognizers.Add(ContentGesture);
Below code in your main page where you add CornerFrame in page
CornerFrame.ItemChanged += (object sender, bool arg) =>
{
if (CornerFrame.IsVisible == true)
{ CornerFrame.IsVisible = false; }
};

Related

How to handle multiple tapping on toolbar item in xamarin forms?

I want to implement enable/disable property of toolbar item.
Here is the scenario,
On toolbar item activation I want to open dialog box.
issue:
When I tapped the toolbar item multiple times then it call multiple times dialog box. Please give some solution to handle the multiple calling of dialog box.
To prevent the multiple clicks, you can use a variable, to prevent calling the Dialog while waiting for the result confirmation.
first, in your class declare a variable canTap;
private bool _canTap = true;
Assuming your method when tapping the toolbar is like this:
private void ItemTapped(object sender, EventArgs args)
{
if(_canTap)
{
_canTap= false;
Device.BeginInvokeOnMainThread(async () => {
var response = await
UserDialogs.Instance.ConfirmAsync(new ConfirmConfig { Message = "Are you sure you want to logout from this app?", Title = "Logout", OkText = "YES", CancelText = "NO" );
if(response)
{
}
else
{
}
_canTap = true;)};
}

How to handle navigation back button event in xamarin iOS/Android?

I am creating xamarin form app and I want to perform some action on navigation back button.Is there any approach to do that?
P.S :> Software back button, not Hardware back button.
In this article, you'll find everything.
IF the article disappears or changes at some point, here you will find the specifics of the solution.
You'll need to create a Custom ContentPage
namespace WhateverYourNamespace
{
public class CoolContentPage : ContentPage
{
/// <summary>
/// Gets or Sets the Back button click overriden custom action
/// </summary>
public Action CustomBackButtonAction { get; set; }
public static readonly BindableProperty EnableBackButtonOverrideProperty =
BindableProperty.Create(
nameof(EnableBackButtonOverride),
typeof(bool),
typeof(CoolContentPage),
false);
/// <summary>
/// Gets or Sets Custom Back button overriding state
/// </summary>
public bool EnableBackButtonOverride
{
get
{
return (bool)GetValue(EnableBackButtonOverrideProperty);
}
set
{
SetValue(EnableBackButtonOverrideProperty, value);
}
}
}
}
As you see, there's an action event that we are going to subscribe to in our Xamarin Forms code level and to be invoked from Xamarin native project level.
There is also a bool property to enable or disable the overriding of the Back Button click event so that you can decide whether to subscribe to the overriding event or not as a page property.
Android :
You'll need to override the OnOptionsItemSelected() event in our MainActivity class in order to capture the nav bar back button click in Android for Xamarin Forms.
public override bool OnOptionsItemSelected(IMenuItem item)
{
// check if the current item id
// is equals to the back button id
if (item.ItemId == 16908332)
{
// retrieve the current xamarin forms page instance
var currentpage = (CoolContentPage)
Xamarin.Forms.Application.
Current.MainPage.Navigation.
NavigationStack.LastOrDefault();
// check if the page has subscribed to
// the custom back button event
if (currentpage?.CustomBackButtonAction != null)
{
// invoke the Custom back button action
currentpage?.CustomBackButtonAction.Invoke();
// and disable the default back button action
return false;
}
// if its not subscribed then go ahead
// with the default back button action
return base.OnOptionsItemSelected(item);
}
else
{
// since its not the back button
//click, pass the event to the base
return base.OnOptionsItemSelected(item);
}
}
public override void OnBackPressed()
{
// this is not necessary, but in Android user
// has both Nav bar back button and
// physical back button its safe
// to cover the both events
// retrieve the current xamarin forms page instance
var currentpage = (CoolContentPage)
Xamarin.Forms.Application.
Current.MainPage.Navigation.
NavigationStack.LastOrDefault();
// check if the page has subscribed to
// the custom back button event
if (currentpage?.CustomBackButtonAction != null)
{
currentpage?.CustomBackButtonAction.Invoke();
}
else
{
base.OnBackPressed();
}
}
iOS :
iOS you need to override the ViewWillAppear() method in your CoolContentPageRenderer class.
So the below code should be placed inside your CoolContentPageRenderer class.
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
if (((CoolContentPage)Element).EnableBackButtonOverride)
{
SetCustomBackButton();
}
}
private void SetCustomBackButton()
{
// Load the Back arrow Image
var backBtnImage =
UIImage.FromBundle("iosbackarrow.png");
backBtnImage =
backBtnImage.ImageWithRenderingMode
(UIImageRenderingMode.AlwaysTemplate);
// Create our Button and set Edge
// Insets for Title and Image
var backBtn = new UIButton(UIButtonType.Custom)
{
HorizontalAlignment =
UIControlContentHorizontalAlignment.Left,
TitleEdgeInsets =
new UIEdgeInsets(11.5f, 15f, 10f, 0f),
ImageEdgeInsets =
new UIEdgeInsets(1f, 8f, 0f, 0f)
};
// Set the styling for Title
// You could set any Text as you wish here
backBtn.SetTitle("Back", UIControlState.Normal);
// use the white color in ios back button text
backBtn.SetTitleColor(UIColor.White,
UIControlState.Normal);
backBtn.SetTitleColor(UIColor.LightGray,
UIControlState.Highlighted);
backBtn.Font = UIFont.FromName("HelveticaNeue",
(nfloat)17);
// Set the Image to the button
backBtn.SetImage(backBtnImage, UIControlState.Normal);
// Allow the button to Size itself
backBtn.SizeToFit();
// Add the Custom Click event you would like to
// execute upon the Back button click
backBtn.TouchDown += (sender, e) =>
{
// Whatever your custom back button click handling
if(((CoolContentPage)Element)?.
CustomBackButtonAction != null)
{
((CoolContentPage)Element)?.
CustomBackButtonAction.Invoke();
}
};
//Set the frame of the button
backBtn.Frame = new CGRect(
0,
0,
UIScreen.MainScreen.Bounds.Width / 4,
NavigationController.NavigationBar.Frame.Height);
// Add our button to a container
var btnContainer = new UIView(
new CGRect(0, 0,
backBtn.Frame.Width, backBtn.Frame.Height));
btnContainer.AddSubview(backBtn);
// A dummy button item to push our custom back button to
// the edge of screen (sort of a hack)
var fixedSpace =
new UIBarButtonItem(UIBarButtonSystemItem.FixedSpace)
{
Width = -16f
};
// wrap our custom back button with a UIBarButtonItem
var backButtonItem = new UIBarButtonItem("",
UIBarButtonItemStyle.Plain, null)
{
CustomView = backBtn
};
// Add it to the ViewController
NavigationController.TopViewController.
NavigationItem.LeftBarButtonItems
= new[] { fixedSpace, backButtonItem };
}
How to use it :
<WhateverYourNamespace:CoolContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:WhateverYourNamespace=
"clrnamespace:XFNavBarBackBtnClickOverride;
assembly=XFNavBarBackBtnClickOverride"
x:Class="XFNavBarBackBtnClickOverride.Page2"
Title="Page 3"
EnableBackButtonOverride="True"
BackgroundColor="#00bfff">
<StackLayout
Spacing="20"
Padding="20,10,20,10"
VerticalOptions="Center"
HorizontalOptions="Center" >
<Label Text="This is the cool page,
which has the Navigation Bar Back button
click overriden. How go ahead and click that Back
button! ;)"
FontSize="20"
HorizontalTextAlignment="Center"
TextColor="White"/>
</StackLayout>
</WhateverYourNamespace:CoolContentPage>
For ANDROID add this in you main activity OnCreate() after LoadApplication(new App()) line.
Android.Support.V7.Widget.Toolbar toolbar
= this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbarSetSupportActionBar(toolbar);

is it possible to define menu as navigation page?

I have a master detail page, and I want to define menu to be a navigation page, so when I select some item in menu, it will open another menu with animation. I tried to create a master as navigation page, and push async new page when selecting an item - but it doesn't work for some reason.
Is it possible at all, or there is other way?
You can have a look at this : https://www.syntaxismyui.com/xamarin-forms-masterdetail-page-navigation-recipe/
This is also a good one to look into
Xamarin.Forms - Master/detail page and navigation history issue
You have to wrap your detail page inside a navigation page so that you get the navigation properties. Is that the bit you are missing?
public class RootPage : MasterDetailPage
{
public RootPage ()
{
var menuPage = new MenuPage ();
menuPage.Menu.ItemSelected += (sender, e) => NavigateTo (e.SelectedItem as MenuItem);
Master = menuPage;
Detail = new NavigationPage (new ContractsPage ());
}
void NavigateTo (MenuItem menu)
{
Page displayPage = (Page)Activator.CreateInstance (menu.TargetType);
Detail = new NavigationPage (displayPage);
}
}

Slide menu from second page in xamarin.forms

When we login,I dont want to display top bar in login_page,from second_page after login I would like to display slide menu.Is it possible to display slide from second page in xamarin.forms?
public class RootPage : MasterDetailPage
{
public RootPage()
{
var menuPage = new MenuPage();
menuPage.Menu.ItemSelected += (sender, e) => NavigateTo(e.SelectedItem as MenuItem);
Master = menuPage;
Detail = new NavigationPage(new DashBoardPage());
}
void NavigateTo(MenuItem menu)
{
Page displayPage = (Page)Activator.CreateInstance(menu.TargetType);
Detail = new NavigationPage(displayPage);
IsPresented = false;
}
}
In App.cs i am using loginpage and in loginpage i dont want ot display top menu.after login i want to display.how to display after login page
public static Page GetMainPage()
{
return new LoginPage();
}
Finally i got the solution for this question:
use:
await Navigation.PushModalAsync(new RootPage());
in place of
await Navigation.PushAsync(new RootPage());

Add drop down menu on button click - windows 8

I want to display a drop down menu when a user clicks a button. Something like comboBox but instead of the comboBox its a button. How can I do it??
I solved it using PopupMenu. Here is the code for other's reference.
public static Rect GetElementRect(FrameworkElement element)
{
GeneralTransform buttonTransform = element.TransformToVisual(null);
Point point = buttonTransform.TransformPoint(new Point());
return new Rect(point, new Size(element.ActualWidth, element.ActualHeight));
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
var menu = new PopupMenu();
menu.Commands.Add(new UICommand("Label", (command) =>
{
//do work
}));
// We don't want to obscure content, so pass in a rectangle representing the sender of the context menu event.
// We registered command callbacks; no need to handle the menu completion event
var chosenCommand = await menu.ShowForSelectionAsync(GetElementRect((FrameworkElement)sender));
if (chosenCommand == null) // The command is null if no command was invoked.
{
}
}
Milan,
You'll need to create a custom control or a user control that combines a button and a popup. You could also just implement this in-place with a button and popup. I suggest you look at Callisto's Menu control and start from there to implement your dropdown menu:
Callisto controls (includes a Menu)

Resources