Page constructor gets called again when navigating back in Windows 8 C# App - windows-8

I have found that in Windows 8 apps, a Page's constructor always gets called again when navigating back to this page, however this is not the case in Windows Phone 7 apps.
Because of this behavior all the properties of that page get lost and you need to somehow store them and reassign them after the page is reactivated. At the moment I am using the SaveState method to save the data and reassign the data in LoadState method. Both of the methods are built-in in the sample Grid/Split App.
I wonder why it's designed this way and if there's any better way to maintain the instance of the page?

You can set Page.NavigationCacheMode = NavigationCacheMode.Required for each page you want to keep in memory, but note that you have to make sure users can't navigate through these pages endlessly as that would leak memory.

Related

Using Frames or changing visibility

I'm new to UWP (windows 10), working on an app for windows phone, I wanted to know what is the difference between:
Using multiple frames and navigate from one to other.
Using a single xaml with no frames but with multiple grids (or other patterns), and instead of navigate- just change visibility so only the desired grid will be visible.
which option is better? and why?
The system keeps track of the Page you are currently on. So even when your App exists and even if it's removed from memory the OS can tell the App to reopen on that page.
Similarily when your App provides other Apps with the capability of calling into it to open certain file types of to perform certain actions (e.g. start navigation, etc.) pages will be used.
Lastly if you put everything on a single page and just manipulate visibility this will increase memory consumption of your App (as everything needs to be loaded even if it's not visible) and it also might increase load times.
Of course how much that impacts you is up to the type of App you are building. In general however I'd advice you to start building using separate pages in case your App grows. Also you get a lot of stuff out of the box if you do so (e.g. animated transitions, etc.)

How can I determine if my Cocoa Desktop application is on the list of apps to be opened at login?

I am developing a SandBoxed Cocoa Application. I have successfully implemented the Launch at login feature by using the Core Foundation function:
SMLoginItemSetEnabled
I have based the implementation on This tutorial
But now I need a way to determine if my app is set to be launched at login, so that I can show the button in the appropriate position upon launch. I would expect a similar Core Foundation function to find out if a bundle identifier is on the list of login items, but I didn't find it.
Another problem is that, by using this Core Foundation approach, although it is recommended by Apple, my app is still inconsistent with the "Open at Login" tick in my application dock menu.
You can do it using the functions in the LSSharedFileList.h header, which is in LaunchServices.framework, which is in CoreServices.framework. As far as I can tell, Apple hasn't documented this stuff except in the header comments, but that's probably enough. The basic outline is that you first create a LSSharedFileListRef using the function LSSharedFileListCreate for the list type kLSSharedFileListSessionLoginItems. Then copy a snapshot of the list (which is a CFArrayRef) using LSSharedFileListCopySnapshot. Then for any item in the array, you can get its URL using LSSharedFileListItemCopyResolvedURL. That last function requires Mac OS X 10.10 or later, while I think the others date back to 10.5.
By the way, the docs on SMLoginItemSetEnabled say that it's for setting an embedded helper app as a login item, but it sounds like you're talking about a freestanding app.
Apple's sandbox documentation says:
With App Sandbox, you cannot create a login item using functions in the LSSharedFileList.h header file. For example, you cannot use the function LSSharedFileListInsertItemURL.
But maybe you can still use the shared file list functions on a read-only basis.

Need to capture if xaml page is idle for 2 minutes

I am new to windows app development. I am currently working on an Universal App using c# and XAML, which has 4 pages, first page being a welcome page. I have to check on other 3 pages (other than welcome page) that if the page is idle for last 2 minutes then I have to reload the welcome page, forcing used to start from the beginning. I did research on this on google, but couldn't find anything helpful. Hope someone from stack overflow community can direct in right direction.
Thanks,
Kevin
Is the welcome page for a login? If you are requiring the user to login to view the extra pages you will also have to handle when the app is in the background. In app.xaml.cs, subscribe to the corewindowvisibilitychanged event. Save a time stamp and now you can check how long the app has been in the background and navigate to the welcome page in the I launched event.
To implement an idle timer you should look at the I launched event where the root frame is created. Subscribe to the pointer moved event in the maimwindow, or use a base page for the similar three pages in your app. When pointer moves, start a dispatcher timer that will be your ticking time bomb for when the navigation occurs. If the pointer moved event happens again, call dispatcher timer.stop, null it out and start a new one. You may also want to subscribe to keyboard events too.
Don't forget to subscribe to pointer moved from the c#, so you can use the overload to handle all events, even when an originating source has already handled it. :)

Application getting slower and slower when navigating

I'm building a Windows Phone application that does video capture in a page and has a custom player in another page. I'm using my own custom codec so the player needs a lot of DispatcherTimer to keep track of several behaviors on the UI part and serve the movie at the good framerate in the codec part.
I'm trying to release all DispatcherTimer as I know they are CPU intensive, but even when stopping them my app is still very slow. If I press back-back then follow the flow, the speed divides by two each time. If I don't use my player, eveything is ok. And my player is only made of 3 DispatcherTimer, a FileStream and an Image box.
I feel that DispatcherTimer are still running in memory and are double-instantiated even if they are instantiated as private on the page directly.
Can I force the page to release all this stuff?
Actually I don't understand yet what is the difference between navigating to a page next to current page, or navigating back. I don't know i.e. how the page is shown again without calling InitializeComponents, so I'm mixed up about which resources to release, and which resources to keep intact.
My execution speed problem was really caused by some running DispatcherTimer, so I'll answer it to have it archived.
The solution:
Ensuring that all DispatcherTimer has been instantiated directly on the page so that we can nullify them from anywhere in the code.
In OnNavigatedFrom, I kill the DispatcherTimer and in OnNavigatedTo, I recreate them with myDispatcherX = new DispatcherTimer();
No "temporary" timers, like "DispatcherTimer myTempTimer = new DispatcherTimer; with ((DispatcherTimer)send).Stop() in callback, as chances are that it remains in memory in an application where we navigate.

WinRt WebView control handling navigation within the control

I have a Metro app using a WebView control. I'm using NavigateToString to load a html file which may contain hyperlinks. What I then want to do is detect when one of these hyperlinks is selected and, instead of allowing navigation within the WebView control, to launch IE and view the page there instead.
Is this possible within the WinRT constraints, and if so, how?
So far, I've tried capturing the WebView_LoadCompleted() event, but although it does fire at the right time, I can't see any details about the URI from the NavigationEventArgs.
Unfortunately this isn't possible directly because WebView does not include events like Navigating (which were present in Windows Phone).
Luckily Nick Randolph (brilliant Windows Phone and Windows 8 developer) has created a workaround using script events. He's got a great write up on his blog:
http://nicksnettravels.builttoroam.com/post/2012/04/21/Limitations-of-the-WebView-in-Windows-8-Metro-Apps.aspx