Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
324 views
in Technique[技术] by (71.8m points)

win universal app - UWP page state manage

I want to learn how to manage the state of a page between navigation. for example a navigate onto page1 and then i navigate to page2, but when i navigate back to page1, the UI elements must already be there with the same data as before and they must not be re-initialized or data must not be binded again by the compiler. Also what I can do to manage state of whole application such that, I terminate the app and then when i launch it next time, the same state is already there as last time. can i apply it on whole application? or what if I only want to apply it on a few pages? any help would be appreciated thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

or example a navigate onto page1 and then i navigate to page2, but when i navigate back to page1, the UI elements must already be there with the same data as before and they must not be re-initialized or data must not be binded again by the compiler.

For this question, you may use UIElement.CacheMode property and Frame.CacheSize property. CacheSize property sets the number of pages in the navigation history that can be cached for the frame, and CacheMode property sets a value that indicates that rendered content should be cached as a composited bitmap when possible.

As we know, an UWP app default using a rootFrame for displaying several pages, we just use Navigation method to change the content in the frame. You can see this in the OnLaunched(LaunchActivatedEventArgs e) method of a blank UWP app. But how to implement cache function? For example, your app has two page and one root frame. You can define CacheSize property in your OnLaunched(LaunchActivatedEventArgs e) method for example:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    ...
    // Ensure the current window is active

    rootFrame.CacheSize = 2;
    Window.Current.Activate();
}

Then in your two pages's constructed functions enable CacheMode property for example:

public MainPage()
{
    this.InitializeComponent();
    this.NavigationCacheMode = NavigationCacheMode.Enabled;
}

Also what I can do to manage state of whole application such that, I terminate the app and then when i launch it next time, the same state is already there as last time. can i apply it on whole application?

For this question, you will need to save the page state in the OnSuspending(object sender, SuspendingEventArgs e) method using Frame.GetNavigationState method, and you can save this state into the app's local settings. For example:

private void OnSuspending(object sender, SuspendingEventArgs e)
{
    var deferral = e.SuspendingOperation.GetDeferral();
    Frame rootFrame = Window.Current.Content as Frame;
    string navstate = rootFrame.GetNavigationState();
    var localSettings = ApplicationData.Current.LocalSettings;
    localSettings.Values["nav"] = navstate;
    deferral.Complete();
}

And how to retrieve this informaton? You can override your OnLaunched(LaunchActivatedEventArgs e) method, and at first you will need to judge how is your app be closed last time, by user, or by system using ApplicationExecutionState enumeration, for example like this:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    //#if DEBUG
    //            if (System.Diagnostics.Debugger.IsAttached)
    //            {
    //                this.DebugSettings.EnableFrameRateCounter = true;
    //            }
    //#endif

    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 (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);
        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated || 
            e.PreviousExecutionState == ApplicationExecutionState.ClosedByUser)
        {
            object value;
            var localSettings = ApplicationData.Current.LocalSettings;
            if (localSettings.Values.TryGetValue("nav", out value))
            {
                rootFrame.SetNavigationState(value as string);
            }
            else
            {
                rootFrame.Navigate(typeof(MainPage), e.Arguments);
            }
        }
        else
        {
            rootFrame.Navigate(typeof(MainPage), e.Arguments);
        }
    }
    // Ensure the current window is active
    rootFrame.CacheSize = 2;
    Window.Current.Activate();
}

But be aware that when an app is closed, next time you launch this app, the UI elements will be re-initialized, this function can only navigate to the page when the last time you close your app, but the data in that page will be lost. But you can also save the data to the local settings and when you navigate to the page, set the value to those UI elements.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...