Navigating between views in Windows 10 XAML - c#

I've tried a number of approaches to this, but when trying to navigate between one page and another in Windows 10 I'm getting some strange behaviour. I display my first page in app.xaml.cs:
View.MainPageView mp = new View.MainPageView();
Window.Current.Content = mp;
This displays the main page fine; however, I have a command that does effectively the same thing for my second page:
View.SecondView dv = new View.SecondView();
Window.Current.Content = dv;
What happens is that it displays the second page, but it is blank. When I try to inspect it using XAML Spy, it shows that the page is there; however, there is no content for it at all (that is, no controls showing).
Is there something particular about Windows 10 that might explain this or, alternatively, is there something about overriding the content in this way that might explain this behaviour?
EDIT:
It appears that the issue is caused by using a bound command, rather than a handled even in order to navigate; the following code works on a click event:
Frame rootFrame = Window.Current.Content as Frame;
rootFrame.Navigated += RootFrame_Navigated;
rootFrame.Navigate(typeof(View.SecondView), null);
But when called from a bound command, whilst it still shows the view, it is always blank. I initially thought this might be relating to the calling thread, but using the UI thread dispatcher makes no difference.

Windows 10 uses the same approach like 8.1.
If you create a new project in Visual Studio and open App.xaml.cs you can find there OnLaunched method. Inside this method you can see that instance of Frame is created and assigned to Window.Current.Content. Frame will help you to manage whole navigation. At the end of this method is navigation to the MainPage.
rootFrame.Navigate(typeof(MainPage), e.Arguments);
If you want to navigate to the second page from the main page, you have to use:
Frame.Navigate(typeof(SecondPage));
In order to go back to the main page just call:
if (Frame.CanGoBack)
{
Frame.GoBack();
}

Related

NavigationView does not switch with page cache enabled/required

In the first page I have a navigation view and have enabled page cache on this page. Without pushing any other page on this, I can switch between tabs. But once I navigate to a new page and then pop back the navigation stops working. If I disable the cache all of the state is lost which I dont want. Tried setting it to required too. The pages are not heavy I tested by creating a sample app with just a textblock.
<Page
...
NavigationCacheMode="Required">
# Navigation View goes here
</Page>
In the page pushed on top of the main navigation page, I have below code to dismiss the page.
private void OnCloseClick(object sender, RoutedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack) { rootFrame.GoBack(); }
}
Once gone back the navigation simply does not work, what am I doing wrong here ?
Stumbled across the same problem and looks like there's a bug in NavigationView class. Long story short, it is not able to properly recover after Load-Unload-Load cycle (e.g. when it is removed from and added back to view hierarchy - which happens when you navigate from page and back) and stops working.
Update: Checked with NavigationView from WindowsUI SDK. Works like a charm, only settings item seems to be broken yet it still has a problem with selecting items with SelectsOnInvoked set to false (aka conditional select).

Force XAML page to reload

I'm trying to figure out how to force a page to completely initialise itself in C# and XAML programmatically (Windows Phone 8.1 Runtime).
(Note this isn't a question about data binding as not a few values need to be updated dynamically, the whole page needs to reinit itself).
The Page class is set up to cache itself as so -
this.NavigationCacheMode = NavigationCacheMode.Required;
I have tried simple answers like setting
this = new Page();
Which doesn't work as current page is obviously read only.
Not entirely sure how to proceed as Page and Frame supply no obvious reload() method or equivalents.
Check if this works:
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame != null)
{
rootFrame.Navigate(typeof(Page));
}

Multiple frames of the same type Windows 8 c#

I have an application for Windows 8 with a page (Frame) for displaying a list of items and a page for downloading & displaying the items details. I am also using MVVM Light for sending notifications.
Application use goes something like this:
Open Main Page
Navigate to List Page
Frame.Navigate(typeof(MyPage));
Choose Item
//Complete logic
Frame.GoBack();
Back on Main Page, I start downloading the file in the view model, I send ONE NotificationMessage saying BeginDownloadFile and after it is downloaded ONE NotificationMessage saying EndDownloadFile.
The first time I do steps 2,3, & 4 my NotificationReceived method is hit once, the second twice and so forth.
private async void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == Notifications.BeginDownloadFile)
{
FileDownloadPopup.IsOpen = true;
}
else if (msg.Notification == Notifications.EndDownloadFile)
{
FileDownloadPopup.IsOpen = false;
}
}
Additional information: I only have one FileDownloadPopup, yet each time, an additional popup is shown each time the NotificationMessageReceived method is called.
My only conclusion is that between navigating forwards and backwards in my app, there are multiple MainPages being created and never closed. This results in many NotificationsMessageReceived methods just waiting for a notification to come their way so they can show their popup.
I have two questions:
1. Does this sound like normal behaviour for a Windows 8 app?
2. How can I close all instances of the MainPage or return to the previous instance without creating a new instance?
Please let me know if I have missed something important out before marking my question down.
This sounds normal to me. The default navigation behaviour in Windows 8 is to create a new page instance each time you navigate to a new page, regardless of whether this is forward or back navigation.
Try setting the NavigatinCacheMode on MainPage to Required. See the MSDN documentation for details of how page caching works.
It sounds like you are registering eventhandlers in the page and then not removing them. Each time you navigate to the page again the handler is being added again in addition to the one you previously added. Try to add your event handler in OnNavigatedTo, and make sure you unregister it in OnNavigatedFrom.
protected override void OnNavigatedTo(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
MyEvent.OnDownloadRequest += MyLocalDOwnloadHandler; // add the handler
}
protected override void OnNavigatedFrom(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
MyEvent.OnDownloadRequest -= MyLocalDOwnloadHandler; // remove the handler
}

RootVisual is null when returning from Tombstoning?

Hi I just found out that my application was crashing when returning from tombstoning. I was able to target the problem here inside the constructor of my page:
RadPhoneApplicationFrame frame = App.Current.RootVisual as RadPhoneApplicationFrame;
frame.PageTransitionCompleted +=
new EventHandler<EventArgs>(frame_PageTransitionCompleted);
Everytime the app is Re-Activated the RootVisual is setting the frame to null. I'm wondering if there is a casting issue here because before I used this code my tombstoning was working perfectly and I was able to navigate freely throughout the app. Any ideas on what might be causing this? Or maybe a work around?
You should move this code from page constructor to OnNavigatedTo method override in your page. Reason is that RootVisual is probably set in RootFrame.Navigated event handler which is generated after page is constructed, not before (this depends of implementation in your App.xaml.cs).
Of course because OnNavigatedTo method may be runned more that once for a page, you should make sure that PageTransitionCompleted event handler is not assigned two times (just use -= before +=).
Another option is to move this code to App.xaml.cs. This makes sense most to me, because that PageTransitionCompleted event is related to whole app, not a single page.

Navigate to existing instance of page in silverlight

On a Frame in silverlight I want to be able to navigate to an existing instance of a Page. In short this is what I want:
Page p = ...; // initialize the page and set some of the properties
contentframe.Navigate(p);
Instead of using an Uri from which the page is created.
Can this be achieved (as in WPF), or should the frame rather be replaced by a ContentControl?
Edit: More clarity: Is there a way that NavigationService.Navigate(object root) that is available in WPF can be simulated in silverlight?
You question seems really quite confused.
should the frame rather be replaced by a ContentControl?
That would imply that you don't have good reason to have the frame there in the first place and you aren't using a navigating framework. In which case certainly you should replace the Frame with something else.
If you can replace the frame with something else the there is no need for your "Page" to be of type Page, it may as well be a UserControl.
It can all boil do down to have this simple Xaml:-
<Border x:Name="content" />
and this cs:-
UserControl p = ...;
content.Child = p;
Edit:
You need to keep the frame therefore you can't replace it with a ContentControl.
You might just assign your Page directly to the Frame Content property. However I'm not sure what would happen if you then click the back button. I suspect it would navigate to the page prior to the page you replaced.
Another option would be to us a static service to push your page properties on to a stack, you page can then pop them off this stack when initialising. This would allow you to navigate using a Uri to your page.
The problem you are facing is the same problem that I am facing. An event happens outside the frame, and the page has no idea that the event has ocured, but it needs to be notified of that event.
Now what can be done is force the page within that frame to refresh itself or handle those events by 1: storing the page's state temporarily, and b) passing "commands" through the query string.

Categories

Resources