I am trying to use PopModalAsync
to remove the modal page. However, the Navigation.ModalStack.Count
is 0. If I use PopModalAsync
, it will throw an exception:
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
I am using Xamarin.Forms
. Here is some sample code:
App.cs (Potable)
public class App : Application
{
public App()
{
// The root page of your application
MainPage = new View.LoginPage();
}
}
LoginPage.xaml.cs (Potable)
public partial class LoginPage : ContentPage
{
public INavigation _Navigate;
public LoginPage()
{
InitializeComponent();
_Navigate = Navigation;
}
async void LoginBtnClicked(object sender, EventArgs args)
{
await _Navigate.PushModalAsync(new AuthenicationBrowser());
//await _Navigate.PopModalAsync(); it is work at here
Debug.WriteLine("Navigation.NavigationStack LoginBtnClicked ===> {0}", Navigation.NavigationStack.Count); //getting 0
Debug.WriteLine("Navigation.ModalStack LoginBtnClicked ===> {0}", Navigation.ModalStack.Count); // getting 1
}
public async void PopModal()
{
Debug.WriteLine(Navigation.NavigationStack.Count);
await Navigation.PopModalAsync();
}
}
AuthenicationBrowser.cs (Potable) * Edited: Put PopModalAsync *
public partial class AuthenicationBrowser : ContentPage
{
public AuthenicationBrowser()
{
InitializeComponent();
}
public async void PopModal()
{
Debug.WriteLine("Navigation.ModalStack AuthenicationBrowser .PopModal===> {0}", Navigation.ModalStack.Count); // getting 0
await Navigation.PopModalAsync();
}
}
BrowserView.cs (Potable)
public class BrowserView : WebView
{
public BrowserView()
{
}
}
AuthenicationBrowserRenderer.cs (Droid) * Edited: Calling PopModal *
[assembly: ExportRenderer(typeof(BrowserView), typeof(AuthenicationBrowserRenderer))]
namespace App.Droid
{
class AuthenicationBrowserRenderer : WebViewRenderer
{
... // Doing some Auth in OnElementChanged and using JavaScriptCallBack class after received json in Webview
}
public class JavaScriptCallBack: Java.Lang.Object, IValueCallback
{
public JavaScriptCallBack()
{
}
public async void OnReceiveValue(Java.Lang.Object result)
{
Java.Lang.String json = (Java.Lang.String)result;
string raw_json = json.ToString();
Debug.WriteLine("raw_json ====>>> {0}", raw_json);
var login_page = new LoginPage();
var auth_page = new AuthenicationBrowser();
Debug.WriteLine(login_page.Navigation.ModalStack.Count); // getting 0
Debug.WriteLine(auth_page.Navigation.ModalStack.Count); // getting 0
auth_page.PopModal(); // Trying to do PopModalAsync
}
}
}
Finally, I may get the answer that App.Current.MainPage.Navigation.PopModalAsync();
can do the trick. The reason is that the new LoginPage()
is called as a new Content Page
not existing page.
If I call it from the App.Current.MainPage
(The existing LoginPage), it can get the existing modal from Modal Stack.
So the solution can be :
public partial class LoginPage : ContentPage
{
public LoginPage()
{
InitializeComponent();
}
async void LoginBtnClicked(object sender, EventArgs args)
{
await Navigation.PushModalAsync(new AuthenicationBrowser());
}
public async void PopModal()
{
Debug.WriteLine("Navigation.ModalStack PopModal ===> {0}", App.Current.MainPage.Navigation.ModalStack.Count);
await App.Current.MainPage.Navigation.PopModalAsync();
}
}
As it seems you had the wrong Navigation
object. In my case I also had this wrong.
I displayed a modal page, which had it's own navigation bar (or Navigation object). So when I wanted to dismiss this modal page I got the mentioned exception, because there were no other pages on the navigation stack. It was the wrong object ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With