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));
}
Related
I am writing an UWP C# application. I am trying to fix my window size during the app launch. To achieve this, I am resizing the window in App.xaml.cs file. Below, the method for the resizing the window.
private void MaximizeWindowOnLoad()
{
var displayInformation = DisplayInformation.GetForCurrentView();
var widthOfScreen = displayInformation.ScreenWidthInRawPixels;
var heightOfScreen = displayInformation.ScreenHeightInRawPixels;
var scaleFactor = displayInformation.RawPixelsPerViewPixel;
var bounds = new Size(widthOfScreen / scaleFactor, heightOfScreen / scaleFactor);
var currentApplicationView = ApplicationView.GetForCurrentView();
currentApplicationView.SetPreferredMinSize(bounds);
ApplicationView.PreferredLaunchViewSize = new Size(bounds.Width, bounds.Height);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
currentApplicationView.TryResizeView(bounds);
}
I call MaximizeWindowOnLoad from OnLaunched method in App.xaml.cs . Below the OnLaunched method.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
MaximizeWindowOnLoad();
Window.Current.Activate();
}
}
The code works fine except one case. After installing the application, on the first launch, the code does not work. I checked, and during debugging the method is being called. I am using the methods from the following thread in stackoverflow. LINK .
I tried to debug to understand the issue. However, the behavior of the method is different for app opening cases (e.g., opening at first and following times). I expected the code to work correct but I don't understand whether it is the problem of UWP or the method is incorrect.
There are two kind of ways that you are using in your code to change the windows size. One is ApplicationViewWindowingMode.PreferredLaunchViewSize and another is TryResizeView.
The behavior you got should be the effect of ApplicationViewWindowingMode.PreferredLaunchViewSize. I think the TryResizeView returns false so it actually has no effect.
PreferredLaunchViewSize
This API is used to set a value to indicate the windowing mode the app launches with. But as it is already mentioned in the Remark part of the document- For the very first launch of an app the PreferredLaunchWindowingMode will always be Auto and the ApplicationView.PreferredLaunchViewSize will be determined by system policies. The API applies to the next launch of the app.
So it's pretty clear about your behavior. The PreferredLaunchViewSize only works when the second time you launch your app. The size of the app is decided by the system when you launch the app for the first time.
TryResizeView
This API is used to change the size of the view to the specified size. It can work in the first time when you launch your app. But in your scenario, it returns false so it does nothing.
The reason why it fails is also mentioned in the Remark part of the document- The resize request has no effect and the method returns false in these cases: The requested size is larger than the available work area.
The available work area is usually smaller than the full screen size due to some reason like the TaskBar. For example, my monitor is 1920*1080 and the scale value is 100%. If I want to call this method successfully, the Max size I could use is 1904*991(Tested).
Summary
If you want to change the size of your window at the first launch, you need to call TryResizeView method and give it a size which is smaller than the full screen size. And set the PreferredLaunchViewSize as full screen size.
When the second time it launches, stop calling the TryResizeView method and let the PreferredLaunchViewSize method changes the windows size to full screen automatically.
I have a little problem. I have to make an app in UWP, and I have to send an item to other page while staying on the same page. And I have no idea how to acomplish that. I have tried different things, but I always ended up on transfering my List to the page, and also transfering view to thta page.
I would really apreciate your help.
If you want to pass parameters when navigating to the page, you can use the following method:
If you don't use the Frame control for navigation
var frame = Window.Current.Content as Frame;
frame.Navigate(typeof(MyPage), myItem);
If you use the Frame control for navigation
frame.Navigate(typeof(MyPage), myItem);
If you are not passing parameters through navigation, you are passing data to another page in the current page. Then we can achieve this in another way.
Suppose we want to modify the data of the parentPage in the childPage, we can add a static object when navigating to the parentPage.
public static MainPage Current;
public MainPage()
{
this.InitializeComponent();
Current = this;
}
public void doSomething(string param)
{
// do something...
}
In other pages, we can make some modifications by accessing this object:
MainPage.Current.doSomething("Hello");
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();
}
I am creating a Quiz program which contains many subjects. But I struck at the following stage. I created many pages and want to load them based on the subject selected. But I don't know how to make it.
Here is what I wanted.
Here Play,Settings and Exit are buttons in main screen. Once you click Play it will show you different subjects available. Once you select the subjects you have different options too.
at first I created Single page and I used grids with hide and show options. But its kind of buggy. So I created pages but I don't know how to navigate between the pages.
How can I achieve it.?
#Ajit,
Yes you can navigate between Pages using :
currentFrame.Navigate(typeof(NextPage));
If currentPage is not this, you can find it the following helper class.
It allows to navigate, even from a ViewModel class :
public class NavigationExtension
{
public static void Navigate(Type typeOfPage)
{
Windows.UI.Xaml.Window window = Windows.UI.Xaml.Window.Current;
if (window != null)
{
Windows.UI.Xaml.Controls.Frame frame = window.Content as Windows.UI.Xaml.Controls.Frame;
if (frame != null)
{
frame.Navigate(typeOfPage);
}
}
}
}
Regards
If you want to go to another page and don't want to come back,
use this code:
Frame rootFrame = Window.Current.Content as Frame;
rootFrame.Navigate(typeof(Your Page Name));
Previously in Windows Phone 8.0 apps, we could navigate deeper to the same page this way:
NavigationService.Navigate(new Uri("/SamePage.xaml", UriKind.Relative));
Page was cached automatically, so after navigating back, user was on the same position on the list when he left.
But in Windows Phone Store Apps we navigate deeper to the same page this way:
Frame.Navigate(typeof(SamePage), id);
But after navigating back it loads data again so if user was on the middle of a long list, now he is on the top:
private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
// TODO: Create an appropriate data model for your problem domain to replace the sample data.
var group = await SampleDataSource.GetGroupAsync((string)e.NavigationParameter);
this.DefaultViewModel["Group"] = group;
}
How can I cache a page like the way it was done previously so user will be on the same position on a list where he left?
(I included Windows apps too cause they are familiar with it from a longer time).
In your page constructor you'll have to specify
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
In App.cs you can set RootFrame.CacheSize which hints the OS how many pages it should try to keep in cache.
Also you probably shouldn't reset the datacontext in NavigationHelper_LoadState - this method is called each time you navigate to the page, even if you navigate back.