Reload page in metro app C# - c#

I'm developing metro app using Windows 8 RTM and C#(VS 2012 RTM), I'm stuck with page reload,
Can any one explains me how to reload page with out navigating to same page again.
Brief: I'm developing metro app with multilingual support. When user selects the language I'm overriding primary language by below code
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "de";
and reload the page by using this code
this.Frame.Navigate(this.GetType());
Language changed to "de",But when i press "Back" on page its navigating same page instead of navigating to previous page.Did i miss something, Can someone please explains me how to do this. Thanks in advance

This will refresh your page:
var _Frame = Window.Current.Content as Frame;
_Frame.Navigate(_Frame.Content.GetType());
_Frame.GoBack(); // remove from BackStack
Handling OnNavigatingFrom() you can save your page's data and state.
Handling OnNavigatingTo() you can load your page's data and state.
As a caveat, my sample does not account for page parameters, you may need to.
Also, another caveat, my sample reloads your page twice. But the GoBack() is necessary to remove the new entry from the BackStack. Unlike WP, Frame does not have Refresh(). Also, the BackStack does not have Remove().
UPDATE
I no longer use the above approach. I use this:
public bool Reload() { return Reload(null); }
private bool Reload(object param)
{
Type type = this.Frame.CurrentSourcePageType;
if (this.Frame.BackStack.Any())
{
type = this.Frame.BackStack.Last().SourcePageType;
param = this.Frame.BackStack.Last().Parameter;
}
try { return this.Frame.Navigate(type, param); }
finally { this.Frame.BackStack.Remove(this.Frame.BackStack.Last()); }
}

I’m not sure I fully understand what you are trying to do, so this may be wrong.
By calling that line of code when you are refreshing the page, you are creating a brand new object of the current type and navigating to it, so this does not save changes the user makes while they are on the current page.
Are you using any type of design pattern? For things like this I use MVVM (using the MVVM light library) which implements a really cool navigation service which will keep stuff like this in check.

Related

How to access PreviousPage property in NavigatedToEventArgs in MAUI

I am trying to determine which was the previous page for current page in .NET MAUI application.
For example, there are 3 pages Page1, Page2, Page3
When going from Page1 to Page2, in Page2, I would like to access PreviousPage property which gives me "Page1" as value.
When going from Page3 to Page2, in Page2, PreviousPage property gives me "Page3" as value.
^^
However, I can only see "PreviousPage" property member in Debug mode when VS hits breakpoint. I cannot access it in code. Intellisense does not show this too.
How can I access and use this "PreviousPage" in my code? Is there any other way?
See screenshot.
I am using:
Microsoft Visual Studio Community 2022 (64-bit) - Preview
Version 17.5.0 Preview 1.0
Thank you.
https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation?view=net-maui-7.0
Navigation events
The Shell class defines the Navigating event, which is fired when navigation is about to be performed, either due to programmatic navigation or user interaction. The ShellNavigatingEventArgs object that accompanies the Navigating event provides the following properties...
Technically you can implement your own custom logic, to see if something has been loaded, what was source, the navigation paths, etc...
Your requirement can be achieved with minimum amount of code.
However, I do not think that navigation stack is a healthy way to check if something is displayed on your page or not.
You could get all the page in Navigation Stack, simply used:
var stack = Application.Current.MainPage.Navigation.NavigationStack;
int count = Application.Current.MainPage.Navigation.NavigationStack.Count;
The current page is the last one, names (count - 1) index (as it is zero-based index) in the stack, so the previous page is (count - 2) index.
Hope it works for you.
Like #h-a-h mentioned, custom logic was the way.
I implemented sort of workaround to make it work. I used navigation parameters.
My viewmodel constructor has attribute like this:
[QueryProperty("IsBack", "IsBack")]
public class Page2ViewModel
{
//called from code-behind on OnNavigatedTo event using associated Command.Execute
async Task LoadData()
{
if(IsBack == false)
{
await _repos.GetListAsync();
}
}
public bool IsBack {get;set;}
}
When going from Page1 to Page2, I do:
await Shell.Current.GoToAsync($"{nameof(View.Page2)}?IsBack={false}");
When going back to Page2 from Page3, I do:
await Shell.Current.GoToAsync($"..?IsBack={true}");
At least this way I know "when" Page2 is visited so as to prevent loading of data again. Though this does not let me know if I am coming back to Page2 from Page3 or Page'n', it solves my current requirement.
One can always use query parameters to provide the parent page.
e.g., from Page5 to Page2, we can do:
await Shell.Current.GoToAsync($"..?IsBack={true}&ParentPageId={nameof(View.Page5)}");
provided Page2's ViewModel has this QueryParameter attribute.
[QueryProperty("ParentPageId", "ParentPageId")]
Not very elegant but workable.
Thank you all for your help.

PuppeteerSharp - Access a background page, that opens in a new tab, as a regular page

I'm having issues with a program that generates reddit apps with refresh tokens from a discord command.
I've managed to get to a point, where I can generate the application, get all the relevant information, head over to https://not-an-aardvark.github.io/reddit-oauth-helper/ and from there generate the token, which opens a reddit confirmation page in a new window.
I've tried accessing it in various ways and have gone through multiple different methods, until I landed on using Target.PageAsync() to get the page.
For some reason, Puppeteer only sees the page as an iFrame and only gives this link when getting the Url property - https://www.redditmedia.com/gtm/jail?cb=8CqR7FcToPI - which doesn't lead to anywhere but seems to be related to the very first iFrame from what I've gathered in the HTML.
I've ran out of ideas on how to access the page to press quite literally one button and would appreciate any ideas or solutions on how to solve this or how to generate the refresh token without the use of an external website.
Another two hours later and I managed to figure out a solution.
Since PuppeteerSharp was unwilling to recognize the page, I just subscribed to Browser.TargetCreated at the correct moment with a handler that, after immediately unsubscribing, will log the most recent target (in this case, a javascript calling window.open()) and take the sender as the Browser, will then try to get the pages into an array and with a bit of code to ensure that it doesn't break itself, I finally managed a solution, I feel kinda dumb after three days and 12+ hours of work.
For anyone who might run into a similar situation, here's the snippet of code that made it finally work:
// Bla bla bla code to crawl or do whatever on the main page.
// Immediately subscribe to the target created event with the event handler
// that will handle the background page once it has
// been triggered by a button, link, etc.
browser.TargetCreated += TargetCreatedEventHandler;
}
static async void TargetCreatedEventHandler(object sender, TargetChangedArgs e)
{
// Unsubscribe from the event to
// make sure there are no duplicate unnecessary calls that might break the code.
browser.TargetCreated -= TargetCreatedEventHandler;
// Since I know the sender is the Browser object,
// I cast it it to another Browser used inside the event handler.
Browser eventBrowser = (Browser) sender;
// Get all the pages from the event browser
// and assume the first page is background one (for now)
Page[] pages = await eventBrowser.PagesAsync();
Page page = pages[0];
int counter = 0;
// Iterate through the pages, check if they're the page you were just on,
// use an int to help you keep track of of indexes.
// If it isn't the page you were on, assign the Page object the page
// with the current counter index from pages.
// (basically make sure it doesn't break itself with the wrong order).
foreach (var item in pages)
{
if (item.Url != "Main Page URL HERE")
{
page = pages[counter];
break;
}
counter++;
}
// Do whatever you need to do on your background page here
}

UWP Navigate throws AccessViolationException for xaml-less pages

Is it just me, or is it impossible to navigate to a page that does not have a .xaml head?
I am constructing a page entirely in code, and I want to navigate to it. I do not want a xaml page because this is a class library and also it is constructed based on data received. I know all about using .xaml to create the page with templates, binding, etc., but I want to avoid that.
When I call Frame.Navigate(typeof(CodePage)), I get nice AccessViolationException.
My page is simple, and so is the navigation. This is the code with a clean, new project
Navigation (button click):
Frame rootFrame = Window.Current.Content as Frame;
rootFrame.Navigate(typeof(CodePage));
Page:
public class CodePage : Page
{
public CodePage()
{
Content = new TextBlock
{
Text = "It works!",
};
}
I know about this issue: Navigate to a Page of another Class Library but, this is because ALL the pages are in the library, I just have 1 specific page in my library. Also, I have other pages in the "launcher" app.
Navigation only works with pages who have xaml part as well because when the page does InitializeComponent in its constructor it sets up the page for Navigation routes and NavigationCache etc.

MVC - Catching a navigation request on the site controller before the LayOut controller

At my company we are discussing wether or not to got and make our next web app in MVC.
I have been charged to figure out some basic stuff which could stop us dead in our tracks, and so have spend some time figureing out the MVC platform as best i could.
There is however one thing im wondering, is it possible, and if so how - to have a menu made on the _LayOut page/controller, which when a user presses a menu navigation i am able to catch on the specfic page before it goes to the layout controller?
UPDATED I forgot to mention that i want to be able to save a form depending on what site i am on. So i may have 10 pages with different forms and depending on which one of these i am on, i have to save the form on that page using the same link in my menu.
My explaning might be abit off so ill quickly describe the scenario and maybe there is another way of doing this.
The user is filling out alot of data on the page, they then press the navigation menu to go to a new page, i want to save the entered data before navigating to the next page for them.
Sorry for my bad english it is not my primary language.
Thanks in advance for any help.
A way to do what you're looking for is to attach a client-side event handler which submits the data before navigating to a new page. It would look something like this:
$(".navigation a").click(function (event) {
// Get form data, process it and POST/PUT/DELETE
});
If you're supporting modern browsers then you can subscribe to the input event of your form and attach yourself on the before unload if anything in your form has changed since the window was loaded as suggested in one of the comments. If you need to support older browsers as well subscribe to the change event of the input fields in the form in order to attach the handler for beforeunload.
form.oninput = function () {
window.onbeforeunload = submitFormData;
};
function submitFormData() {
// Gather and submit your data
}

How to store state in Windows 8.1 using Blank Page Template?

I am migrating my Windows Phone 8 App to Windows 8.1 App and I have created a Page with blank page template. In that there are some Items like TextBlock,ComboBox and TextBox. Now, there is an item LocationTextBlock with border around it. When I click on it, it navigates to a new Page LocationPage, where I need to select location and save that object and navigate using Frame.GoBack() method. Now the issue, when I navigate back, I get the object of LocationData but the LocationTextBlock which was created previously is showing null, so I can't populate Location in that TextBlock.
Questions
Is this issue occurring due to Blank Page Template ?
Can it be solved using NavigationHelper Class?
Will using Basic Page Template resolve this issue?
Please suggest with some code or description, whether it can be done using Blank Page template as I have added many lines of code inside it.
It can be done with Blank Page template (although using NavigationHelper would be the prefered way).
What you have to do is set NavigationCacheMode to Enabled in your Page's Constructor:
this.NavigationCacheMode = NavigationCacheMode.Enabled;
This way the Page with all the properties in it is cached. So when you navigate back you get back the state in which the Page was when you navigated from it. However, if you navigate to this page not through backnavigation, you'll still get back the saved state, which you don't want. The solution is to clean up all the resources (initializing the needed variables, setting UI elements to default value etc.) in the OnNavigatedTo(NavigationEventArgs e) method if (e.NavigationMode != NavigationMode.Back). Don't know if it's the best approach, but it'll work.
EDIT:
You could even use a Flyout or a ContentDialog instead of your LocationPage, so you don't need to navigate from the page, thus not needing to cache/save the page.

Categories

Resources