Xamarin re-navigation to mainpage from viewmodel displays empty page - c#

When I re-navigate to my first page (Called Mainpage) from a viewmodel it displays an empty page.
I understand that this is related to the stack but no matter what I try it stays empty. Does anyone has any ideas? I find related threads but not in the same way.
Mainpage constructor:
public Login()
{
InitializeComponent();
}
Code in the viewmodel
await Application.Current.MainPage.Navigation.PopToRootAsync();
await Application.Current.MainPage.Navigation.PushAsync(new Login());
Ok so for extra info:
Setting my rootpage:
public partial class App : Application
{
public App()
{
InitializeComponent();
NavigationPage navigationPage = new NavigationPage(new Login()); << Renamed mainpage to login after the suggestion over here
MainPage = navigationPage;
}
I call my rootpage after login. I want to make sure my code logs-out my user after the person his/hers ADAL token has expired. It would happen like this in my viewmodel:
var auth = DependencyService.Get<IAuthenticator>();
auth.logout();
await Application.Current.MainPage.Navigation.PopToRootAsync(true);
(Without pushAsync is does not navigate at all and stays at the current page. This is called straight after the new page is loaded and the user is logged-in)

In your App.cs you should have defined a NavigationPage passing the root of your navigation stack.
Let's say:
public class App : Application
{
public App ()
{
NavigationPage navigationPage = new NavigationPage (new MainPage ());
MainPage = navigationPage;
}
}
The root of your application will be MainPage.
Wherever in your application will call the Navigation.PopToRootAsync(); method, you'll go back to your root page. (MainPage in this case)
You don't need to push in the stack the MainPage because it's already there, you're popping out all the pages excluding the root.
The constructor of the page won't be called but you can rely on the Appearing event that is fired when the page is displayed.

initialize static NavigationPage variable in App.cs
public class App : Application
{
public static NavigationPage NavPage;
public App ()
{
NavPage= new NavigationPage (new MainPage ());
MainPage = NavPage;
}
}
use NavigationPage variable of App.cs for navigate main page from third page
public partial class thirdPage : ContentPage
{
public thirdPage ()
{
InitializeComponent ();
main.Clicked += Main_Clicked;
}
private void Main_Clicked(object sender, EventArgs e)
{
App.NavPage.PopToRootAsync(true);
}
}

Related

App.Current.MainPage NullReferenceException in Constructor of MainPageModel

On the loading of MainPage, I am pushing another page from Constructor of MainPageModel. It throws NullReferenceException in MainPageModel. This is my code
MainPage constructor
public MainPage()
{
InitializeComponent();
Title = "MainPage";
BindingContext = new MainPageViewModel();
}
MainPageModel constructor
public MainPageViewModel()
{
App.Current.MainPage.Navigation.PushAsync(new HomePage()); //Exception
//CommandMenu1 = new Command(async () => await NavigateNext());
}
How can I solve this issue?
What probably happens is this:
public class App
{
MainPage = new MainPage();
}
The MainPage() constructor has to be completed before it is assigned to the MainPage property of your App. Therefore, trying to access the App.Current.MainPage before then, you will get a NullReferenceException. This means you will have to find another way to achieve what you are trying to do here.
You are trying to access MainPage in your View Model before it has been fully initialized. Instead of binding in your MainPage constructor bind in App.xaml.cs
public App() {
InitializeComponent();
MainPage = new MainPage();
MainPage.BindingContext = new MainPageViewModel();
}
Use OnAppearing() instead of MainPageViewModel() to give it time to load fully,
Code :
protected override async void OnAppearing()
{
App.Current.MainPage.Navigation.PushAsync(new HomePage());
}
Hope it helps!
You can try the code below:
await Navigation.PushAsync(new NewPage());
on New Page.Cs
InitializeComponent();
NavigationPage.SetHasBackButton(this, false);

Navigate Content Pages MVVM xamarin

Can someone teach me how to navigate between pages of content? I have been reading many tutorials but I have not been able to achieve it. I have this small code I want to achieve that when pressing the buttons I change between the pages. I use MVVM model there is my MainViewModel
public class MainViewModel
{
public Page1 PageNumberOne { get; set; }
public Page2 PageNumberTwo { get; set; }
public MainViewModel()
{
this.PageNumberOne = new Page1();
}
}
there is my view model of Page1
public class Page1
{
#region constructor
public Page1()
{
GoPage2Command = new Command(async () => await GoPage2());
}
private async Task GoPage2()
{
await Application.Current.MainPage.DisplayAlert("", "Goin to page 2", "ok");
//code to go PageNumberTwo here
}
#endregion
#region Commands
public Command GoPage2Command { get; set; }
#endregion
}
GoPage2Command is binding to a button.
there is my complete project up load to MF VS proyect
Simply call
Navigation.PushAsync(new ContentPage());
INavigation.PushAsync Method
Asynchronously adds a Page to the top of the navigation stack.
Example from the page
var newPage = new ContentPage ();
await Navigation.PushAsync (newPage);
Debug.WriteLine ("the new page is now showing");
var poppedPage = await Navigation.PopAsync ();
Debug.WriteLine ("the new page is dismissed");
Debug.WriteLine (Object.ReferenceEquals (newPage, poppedPage)); //prints "true"
Your Exmaple
private async Task GoPage2()
{
await Application.Current.MainPage.DisplayAlert("", "Goin to page 2", "ok");
//code to go PageNumberTwo here
Navigation.PushAsync(new PageNumberTwo());
}
I found the problem, I was using Xamarin Live to do the tests, connecting by cable does not give any error. I do not recommend using Xamarin Live not only gives that problem but many more

Xamarin portable, how to navigate back from selected list item to MainPage and pass value

My previous question was, how to navigate from ToolbarItem to another page and keep navigation bar existing. : Xamarin portable project navigate with ToolbarItem to another page by using MasterDetailPage
Now I have troubles when I select item from item list and I want to back to my MainPage, but I am getting such a error: System.Exception: Android only allows one navigation page on screen at a time and MainPage page appear, but it freeze and I see now 2 buttons on navigation bar. But it should be only one.Here in MainPage I am calling Cities:
public partial class MainPage : MasterDetailPage
{ public MainPage()
{
InitializeComponent();
masterPage.ListView.ItemSelected += OnItemSelected;
CityClick.Clicked += async (sender, e) =>
{
await Detail.Navigation.PushAsync(new Cities());
};}}
Then when I am at Cities.xaml.cs I want to back to MainPage(). And also I want pass my selected item value from list to my label in MainPage.xaml navigation. Second problem is when I am returning from Cities.xaml.cs after item select to MainPage() I am getting that error which I mentioned before. This is my Cities class:
public partial class Cities : ContentPage
{
public Cities()
{
InitializeComponent();
Label header = new Label
{
Text = ...
};
List<City> cities = new List<City>
{new City("City1"),
new City("City2")};
ListView listView = new ListView
{ItemsSource = cities,
ItemTemplate = new DataTemplate(() =>
{
Label nameLabel = new Label();
nameLabel.SetBinding(Label.TextProperty, "Name");
BoxView boxView = new BoxView();
return new ViewCell
{
...
};
...
{
Children =
{
...
}
};
listView.ItemSelected += async (sender, e) =>
{
if (e.SelectedItem == null)
{return;}
else
{
await Navigation.PushAsync(new MainPage());
}
};
}
class City
{public City(string name)
{
this.Name = name;
}
public string Name { private set; get; }
};}
And this is how looks when returns to MainPage() it freeze everything and appear another label:
EDIT : Regarding #AkashAmin comments I changed from await Navigation.PushAsync(new MainPage()); to await Navigation.PopAsync(); and it is worked very well. Now I still have dilemma with pasiing value from City class to MainPage class.
I navigated back from my Cities class to my MainPage by changing from PushAsync to PopAsync(); . Thank you #Akash Amin for your information. This awaited task also solved duplicated labels problem in Navigation ToolbarItems place .
Also I solved value passing from Cities to MainPage class problem. In this link you can see my all walkthrough of solving this problem: https://stackoverflow.com/a/37350738/3727758

How to open new TabbedPage from ContentPage?

I am trying to open (using any method) the TabbedPage from ContentPage.
My main App code:
public class App : Application
{
public App ()
{
MainPage = new ConnectPage ();
}
}
My ConnectPage uses XAML, code:
.cs file:
public partial class ConnectPage : ContentPage
{
public ConnectPage ()
{
InitializeComponent ();
}
void connectDevice(object sender, EventArgs args){
connect_btn.Text = "Connecting...";
connect_btn.IsEnabled = false;
var mainapp_page = new MainApp ();
Navigation.PushAsync (mainapp_page);
}
}
XAML file:
<Button x:Name="connect_btn" Text="Connect Now" Clicked="connectDevice"></Button>
Above method throws error:
PushAsync is not supported globally on iOS, please use a
NavigationPage
My MainApp.cs (which contain tabs):
public class MainApp : ContentPage
{
public MainApp ()
{
var tabs = new TabbedPage ();
tabs.Children.Add (new Tab1Page{Title="Tab1" });
tabs.Children.Add (new Tab2Page{Title="Tab2" });
tabs.Children.Add (new Tab3Page{Title="Tab3" });
}
}
You can either update your'r app's MainPage property and set that to the page you want to display, use stack navigation or present a page modally.
Setting a new main page will provide no way for the user to go back:
App.Current.MainPage = new SomeOtherPage ();
If you want to use stack navigation, you will have to wrap your initial page into a NavigationPage:
public partial class App : Application
{
public App ()
{
InitializeComponent ();
this.MainPage = new NavigationPage (new FirstPage ());
}
}
Than you can use Navigation.PushAsync().
If you want to present a page modally, so it is shown on top of your current page and can be dismissed, use:
Navgiation.PushModalAsync(new Page());
However, this will still require to wrap your current page into a NavigationPage.
There are other ways too, like CarouselPage or MasterDetailPage. I recommend you look at the documentation for all of your options.

WPF application send parameters (MvvmLight with Page navigation)

I have a WPF application with Page navigation. I use MvvmLight toolkit. I have two pages: FirstPage (default page) and SecondPage. On FirstPage I navigate to SecondPage.
I want to pass a parameter to SecondPage.
//code on FirstPage
NavigationService.NavigateTo(new Uri("SecondPage.xaml", UriKind.Relative));
Messenger.Default.Send<string>("my mess");
//code on SecondPage
//constructor
public SecondPage()
{
Messenger.Default.Register<string>(this, GetMess);
}
private void GetMess(string obj)
{
}
When you first start it's not working. I can create an instance of SecondPage,
PageSecond page = new PageSecond();
but it is not beautiful. Help me please.
You are not following the MVVM principle with code like this in the code-behind. So following your start here is a simple (non-MVVM) way answer this:
Code on FirstPage -
Page secondPage = new SecondPage("Hello");
NavigationService.Navigate(secondPage);
Code on SecondPage
// Public parameterless constructor - needed for designer
public SecondPage()
{
InitializeComponent();
}
// Constructor with parameter
public SecondPage(string parameter)
{
InitializeComponent();
MyTextBox.Text = parameter;
}

Categories

Resources