How to call the previous page function in MAUI? - c#

My problem:
My parent page (AdminPanel.xaml) contains a function: updateAllMaterialList()
It's the page previous one on the navigation stack.
Now on the AddUser.xaml page, I try to navigate back by calling updateAllMaterialList() like this:
private async void GoToBack(object sender, EventArgs e)
{
await Navigation.PopAsync();
NavigationPage navPage = (NavigationPage)App.Current.MainPage;
Page page = navPage.Navigation.NavigationStack[navPage.Navigation.NavigationStack.Count - 1];
((AdminPanel)page).updateAllMaterialList();
}
But it doesn't work

First I want to point out, that there is good reason not keep your business logic in your pages.
I recommend that you check CommunityToolkit.MVVM/MAUI.
And then add some service, to do this work for you.
Or use EvenToCommandBehavior to bind your page events.(Appearing, Loading, etc..)
Or use Messenger to send/receive data between decoupled segments.
The way you are attempting to handle your logic and navigation will bring a lot of problems. One page navigation should have nothing to do with another page business logic.

As Jason said, you can Generate OnAppearing method override in AdminPanel.xaml.cs, and add updateAllMaterialList() function to OnAppearing. So, whenever the AddUser.xaml page navigates to the AdminPanel.xaml page, it will call updateAllMaterialList() automatically. OnAppearing means that when the specified page appears, it will be called.

Yes, as they said, you can use the OnAppearing and everything works great. But I also found this way:
var navPage = App.Current.MainPage;
if (navPage.Navigation != null)
{
navPage = navPage.Navigation.NavigationStack[navPage.Navigation.NavigationStack.Count - 2];
(navPage as AdminPanel).UpdateAllMaterialList();
}

Related

Best practice to place a function which executes automatically on each page call

I have a scenario as follows,
I'm having an application in that i need to execute a function, which needs to be executed before page load of each pages. even if i add a new page, the function needs to be execute with out copying that function into the new page.
Please guide me Best practice to place the function in an application, so that it will work as i stated.
If your answer is master page, then in Master page which event is the best place to write the function code?
The process of the function is to call DAL class and get data from database , get the page name and need to do some login based on the page name.
Thanks and regards
consider using custom HttpModule
http://msdn.microsoft.com/en-us/library/ms227673.aspx
or in Global.asax you can hook up desired event in Application_PreRequestHandlerExecute:
void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
if (context.Handler is Page)
{
Page page = (Page)context.Handler;
page.Load += ...
}
}
}
If you are using MVC, then a possible approach could be to make a call in _Layout page.

Xamarin Forms Navigation and dealing with a Login Page

I'm trying to create an App with a Login Page as the first page.
Once the user logs in, the pages that come after will be in a standard page stack organisation so I can easily use the build in Navigation object and wrap everything in Navigation pages.
e.g.
Login Page -> MainAppPage |-> Category1Page -> Cat1SubPage
|-> Category2Page -> Cat2SubPage
My understanding is that I should wrap MainAppPage with new NavigationPage(), and then I'll have access to the Navigation object allowing me to do things like this:
await this.Navigation.PushAsync(new Category1Page());
And the various platforms will give me automatic back button support to go back to the previous page.
But I don't want a user to navigate from LoginPage -> MainAppPage in this manner, because I don't want the backbutton to take them back to Login, without them explicitly hitting the logout button.
So how should I handle that first Page Transition from LoginPage -> MainApp Page.
Is there an alternative way to have 2 Primary pages and swap between them? Or is there a way to intercept the back button requests on MainAppPage and discard them?
Not finding an awful lot of info in the documentation regarding this, but it seems like a fairly standard requirement so possibly PEBKAC
I just posted a quick sample on Github for this scenario. The idea is that you want to initially navigate to your NavigationPage, then if necessary (meaning the user isn't already logged in), push the LoginPage modally. Then, on successful Login, simply pop the LoginPage from the stack. You can check out the sample here, https://github.com/jamesqquick/Xamarin-Forms-Login-Navigation/blob/master/ReadMe.MD
I can think of at least two solutions.
One way is to create a MainAppPage first and within that page show Login Page as Modal.
Other would be to create a platform specific page, load Login Page and only upon successful login navigate to MainPage using platform specific navigation (LoginPage should be NoHistory or something like that to avoid going back) not Forms navigation (i.e. in Android both pages should be separate activities). This involves a bit more work since you have to deal with the three platforms but it shouldn't be much overhead.
That said there is a better navigation supposedly coming with, hopefully, 1.3.0.
As Miha Markic said, a Modal window is a good option. One other thing you can also consider, especially if you want the login page to have the same Navigation Bar as your other pages, would be the same thing that I already posted about in the question URL below.
Basically, you would keep a reference to your NavigationPage in the App class (lets call it AppNavPage), then, when showing your login page, you put your login page within a separate NavigationPage and do a PushAsync() with your new NavigationPage and login page.
Once the user logs in successfully, you just replace the current MainPage with your old NavigationPage using this code:
Application.Current.MainPage = App.AppNavPage
Check out the link below for better code examples.
https://stackoverflow.com/a/32382852/3850012
This is what I have working on Android:
protected override void OnCreate (Bundle bundle){
base.OnCreate (bundle);
string start = "new";
Bundle extras = Intent.Extras;
if (extras != null) {
start = extras.GetString ("start");
}
if(start == "new"){
SetPage (App.GetLoginPage (OnLoginCompleted));
} else if (start == "login") {
SetPage (App.GetMainPage (OnSignOutCompleted));
}
}
void OnLoginCompleted(){
// ...
var refresh = new Intent (this, typeof(MainActivity));
refresh.PutExtra ("start", "login");
StartActivity (refresh);
Finish ();
}
void OnSignOutCompleted(){/* mirrors OnLoginCompleted */ }
This is effectively an activity with a configurable landing page. In order to change to it we restart with a different setting. It's a tiny bit slower than navigating on my phone but only just noticeable.
I think the best way would be to Remove the LoginPage from the stack once you verify login, then it's not available any longer.
async void OnLoginButtonClicked (object sender, EventArgs e)
{
...
var isValid = AreCredentialsCorrect (user);
if (isValid) {
App.IsUserLoggedIn = true;
Navigation.InsertPageBefore (new MainPage (), this);
await Navigation.PopAsync ();
} else {
// Login failed
}
}
Provided that the user's credentials are correct, the MainPage
instance is inserted into the navigation stack before the current
page. The PopAsync method then removes the current page from the
navigation stack, with the MainPage instance becoming the active page.
See full description here

Do I need to cleanup after using System.Reflection in an aspx page?

I have the following method that is called when reloading certain pages in my app. The point being to interrupt the current transaction, ask for authentication and call a specified function when coming back to the page to complete the transaction. State, and the method name are saved in Session in the interim.
After redirecting back to the page, the method executes and everything looks fine, but when clicking on a link to the same page it now just displays the same page, not a new page with empty fields etc. and, no page events fire. Eventually if I leave the page for long enough, maybe 5 minutes, it will refresh the page or clicking a button with a Response.Redirect call will do it.
Call the same page method normally w/o reflection and it looks to be fine. It seems as if using reflection may be keeping the page object in memory and not allowing it to be GCed. What is going on here? There are plenty of workarounds, but I'd still like to understand it for the future.
protected override void OnLoadComplete(EventArgs e)
{
base.OnLoadComplete(e);
if (IsRestoredPageState && priorPageState.CallingFunction != null)
{
var completeAction = this.GetType().GetMethod(priorPageState.CallingFunction);
completeAction.Invoke(this, null);
completeAction = null;
}
}

Activating a ASP Multiview control's view from other page without querystring/session

I was looking for an alternative that may be used to activate a multiview control of other page without passing a querystring/session variable.
Basically, my Home.aspx page has a link that takes us to a specific page say "NewPage.aspx". The NewPage.aspx page has a multiview control that has three child views.
I want to click on the link of the Home.aspx and go to NewPage.aspx with MultiView1.ActiveViewIndex=1. Please remember that I do not want to pass any querystring variable as that link already contains some encrypted data as querystring and adding another variable can cause the data to corrupt. Maintaining a session isn't a solution as well because the application is quite big.
Any inbuilt method that can activate that view? (I don't seem to be talking practical but any help is really appreciated)
If you are asking about how navigate to this page I would wire up a button event (I prefer to do so in OnInit). Something like this:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.btnlinkclick.Click += new EventHandler(btnlinkclick_Click);
}
void btnlinkclick_Click(object sender, EventArgs e)
{
this.MultiView1.ActiveViewIndex = 1;
}
This should work for you.

Submit value of a TextBox without reloading page

I'm working on an ASP.NET based TicTacToe game. The problem I have with it is that:
The game is played between two users. When the first one types 'x' in the TextBox I want the 'x' to be shown on the second player's computer without reloading the page.
I don't know if some code will help but here is the way I did it without reloading(the user must reload the page manually... dumb):
protected void TopLeft_TextChanged(object sender, EventArgs e)
{
Application.Lock();
GameBoard gameBoard = new GameBoard();
gameBoard.board[0, 0] = char.Parse(this.TopLeft.Text);
Application["TopLeft"] = gameBoard.board[0, 0];
Application.UnLock();
}
And then, on page pre render:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
Application.Lock();
if(Application["TopLeft"] != "0")
{
this.TopLeft.Text = Application["TopLeft"].ToString();
}
...
And so on...
I'd be very thankfull to anyone who can help!
You will need to use AJAX to do this. I recommend looking at some of the AJAX capabilities that jQuery offers but you can also look at the AJAX Toolkit from Microsoft.
Here is documentation for AJAX in jQuery:
http://api.jquery.com/jQuery.ajax/
I feel this is much "lighter" than what Microsoft offers out of the box. You can find out more about the Microsoft AJAX toolkit here:
http://www.asp.net/ajax/ajaxcontroltoolkit/samples/
You are asking about Partial Page Update.
First, you need to place the client TextBox or what ever other controls that you need to reload inside an UpdatePanel.
Then, you need to call the UpdatePanel.Update to update those controls whenever you need.
Check out AJAX. This will require client scripting to submit and detect updates without submitting or updating the entire page.
Note, however, that this is a fairly advanced topic and will not simply be a little snippet of code you can add. I would recommend a good AJAX/JavaScript/jQuery book.

Categories