NEW FEATURE: Application Tombstoning and Cascading State Management

274 views
Skip to first unread message

Rishi Oberoi

unread,
Feb 5, 2011, 11:32:29 AM2/5/11
to nro...@googlegroups.com
Recently I wrote about a new feature that allows navigation-containers to save and restore view state (from the View) in addition to the logical state (from the ViewModel). Now, I've extended the use of the view-state management functionality to allow for dehydrating and hydrating of the navigation-container's state. What does that mean, it means navigation-container's internal state (which contains the navigation history, navigated urls info, visual-state, logical-state etc) can be extracted and inserted back. Furthermore, this state can also be serialized and de-serialized to allow for persisted tomb-stoning for either the full application or part of the application.  

In terms of the implementation, all the built-in navigation containers now implement ISupportNavigationViewState, which again looks like:
    public interface ISupportNavigationViewState 
    {
        void RestoreState(ParametersCollection state);

        ParametersCollection SaveState();     }
So, to get the state it's just a matter of calling SaveState, and equally use RestoreState method to restore the state - nothing special there. The interesting thing is that you can take this state are serialize it and derserialize it - and it would basically restore everything from the page's View/ViewModel-state, back/forward navigation history, etc etc. However, you need to be mindful that anything you've stored in the state (either in the View or ViewModel) needs to be serializable, and the serializer needs to be made aware of it. For example, in one the sample in the repository, I store a "Person" object in my ViewModel's state - and so in addition to the types the container uses the person type must be made known to the serializer (note I'm working a some infrastructure to make this auto-discoverable):
    var _state = ((ISupportNavigationViewState)this.shell).SaveState();
    var _memStream = new MemoryStream();
    var _serializer = new XmlSerializer(typeof(ParametersCollection), new Type[] { typeof(Parameter), typeof(PageContentState), 
        typeof(PageContentState[]), typeof(Object[]), typeof(Object[][])
typeof(Person) });    // note the custom type - Person 
    _serializer.Serialize(_memStream, _state);

    PresistState(Encoding.UTF8.GetString(_memStream.GetBuffer(), 0, Convert.ToInt32(_memStream.Length)));
The same logic stands when deserializing. Also, if you are going to use this capability put some thought around what you store in the state especially with reference types, and pls don't start storing control instances because you'll start leaking memory by the dozen. 

The second use of having the navigation-containers be able to save and re-store state is to allow for cascading state management. In any complex application you'll often see that you have a shell-container that hosts the top-level content, and then the top-level content UIs are themselves composed of many sub-sections again using navigation-containers - a simple example would be where you have a side-panel. Now the problem earlier with such a setup was that when you navigated at the top-level the top-level content's ViewModel would persist its state but all the View/ViewModel state of the side-panel/inner-sections would be completely lost (without some manual intervention). However, now with the addition of View state and Navigation-Container state capabilities, what you can do is: save the inner-container's state from within the View when the View's SaveState method is called and vice-versa when restoring. In the example below, I have a top level page that hosts two sub-containers - and when saving/restoring the View's state I can save/restore the inner container's state:
    public partial class Shell : UserControlISupportNavigationViewState
    {
        public void RestoreState(nRoute.Components.ParametersCollection state)
        {
            var _leftState = state.GetValueOrDefault("LEFT"default(ParametersCollection));
            var _rightState = state.GetValueOrDefault("RIGHT"default(ParametersCollection));
            if (_leftState != null) ((ISupportNavigationViewState)leftContainer).RestoreState(_leftState);
            if (_rightState != null) ((ISupportNavigationViewState)rightContainer).RestoreState(_rightState);
        }

        public nRoute.Components.ParametersCollection SaveState()
        {
            return new ParametersCollection()
            {
                new Parameter("LEFT", ((ISupportNavigationViewState)leftContainer).SaveState()),
                new Parameter("RIGHT", ((ISupportNavigationViewState)rightContainer).SaveState()),
            };
        }
    }
And if you've set-it-up right, then this would cascade to n-levels. Also, you can also implement this functionality with other sorts of controls - for example, with a Tab-Control you could possibly get a listing of all the tabs open and serialize/derserialize the navigation-containers state within each tab along with a listing of the tabs. 

I think this has a lot of uses and expands the horizons of what applications can do - for example, you can serialize the state to a db and when the user logs in, possibly on another computer, he/she can resume where they left as if nothing changed. Further, I'll be integrating this with WP7's tomb-stoning infrastructure - so if you use nRoute, you'll get tomb-stoning feature for free.

Lastly, I'd appreciate if anyone can test this with some meaty examples, and let me know either about any edge-cases I've missed or issues otherwise.

Cheers,
Rishi

Gerhard Kreuzer

unread,
Feb 9, 2011, 4:01:28 PM2/9/11
to nro...@googlegroups.com
Hi Rishi,
 
cant find 'tomb-stoning' at www.leo.org, so what is another term for that?
 
Thanks
 
Gerhard


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Rishi Oberoi
Gesendet: Samstag, 05. Februar 2011 17:32
An: nro...@googlegroups.com
Betreff: [nRoute] NEW FEATURE: Application Tombstoning and Cascading State Management

Adrian Hara

unread,
Feb 10, 2011, 2:42:41 AM2/10/11
to nro...@googlegroups.com

Hi Gerhard,

 

Read this: http://wildermuth.com/2010/10/17/Architecting_WP7_-_Part_5_of_10_Tombstoning 

 

Tombstoning is a windows phone 7 concept whereby an application is closed by the OS under certain conditions, but gets a chance to save its state so it can be resumed from the same “screen” later. I guess a similar term for “tombstoned” would be “suspended”…

 

Cheers,

Adi

 

Freundliche Grüsse / Best regards

Adrian Hara
Cloud Developer
LinkedIn 


coresystems ag
Villa im Park | Dorfstrasse 69
5210 Windisch | Switzerland


Phone +41 56 500 22 22
Fax +41 56 444 20 50
Infoline +41 848 088 088
www.coresystems.ch
www.coresuite.com
follow us on
twitter

Visit us at CeBIT:
SAP Partner Booth: Hall 5, Booth A18
Cloud Computing: Hall 4, Booth A58
OS X Business Park: Hall 2, Booth A20
Microsoft Booth: Hall 4, Booth P47

The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and / or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Gerhard Kreuzer

unread,
Feb 10, 2011, 2:48:31 AM2/10/11
to nro...@googlegroups.com
Thanks, I read this so, exactly, but was not sure, because they used this new word instead of suspended ....
 
With best regards
 
Gerhard


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Adrian Hara
Gesendet: Donnerstag, 10. Februar 2011 08:43
An: nro...@googlegroups.com
Betreff: RE: [nRoute] NEW FEATURE: Application Tombstoning and Cascading State Management

Gerhard Kreuzer

unread,
Feb 10, 2011, 4:21:36 AM2/10/11
to nro...@googlegroups.com
Hi,
 
my 'Proof of Concept' app is running, while showing some error in design mode. Any idea?
(See attached image)
 
With best regards
 
Gerhard


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Adrian Hara
Gesendet: Donnerstag, 10. Februar 2011 08:43
An: nro...@googlegroups.com
Betreff: RE: [nRoute] NEW FEATURE: Application Tombstoning and Cascading State Management

app running but designer problems.JPG

Gerhard Kreuzer

unread,
Feb 10, 2011, 6:20:54 AM2/10/11
to nro...@googlegroups.com
Hi,
 
Rishi, I finally found out, that if the user clicks a navigation link, but the associated view is still present, the whole stuff (New, OnInitialize ...) is fired, but for nothing, because the view is up to date and was never destroyed.
 
Maybe you can build in some check to prevent this actions, because complex views with sub views holding sub containers making heavily use of the de/re-hydration can couse lot of system burden just for nothing.
 
Thanks a lot.
 
With best regards
 
Gerhard


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Gerhard Kreuzer
Gesendet: Donnerstag, 10. Februar 2011 10:22
An: nro...@googlegroups.com
Betreff: AW: [nRoute] NEW FEATURE: Application Tombstoning and Cascading State Management

Gerhard Kreuzer

unread,
Feb 10, 2011, 8:02:40 AM2/10/11
to nro...@googlegroups.com
Hi,
 
I am using nRoute5 Set 57081, but can't find this new feature.
Just blind, or isn't included yet.
If not included yet, is some guess available, when I can start testing it?
 
With best regards
 
Gerhard


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Adrian Hara
Gesendet: Donnerstag, 10. Februar 2011 08:43
An: nro...@googlegroups.com
Betreff: RE: [nRoute] NEW FEATURE: Application Tombstoning and Cascading State Management

Rishi Oberoi

unread,
Feb 10, 2011, 8:10:51 AM2/10/11
to nRoute
Hi Gerhard, I'm not looking into designer issues yet - will do so,
once I'm feature complete.
Rishi

On Feb 10, 12:21 pm, "Gerhard Kreuzer" <gerhard.kreu...@liftoff.at>
wrote:

Gerhard Kreuzer

unread,
Feb 10, 2011, 8:15:05 AM2/10/11
to nro...@googlegroups.com
Ok, just want to deposit this, as I struggle over it.

-----Ursprüngliche Nachricht-----


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von
Rishi Oberoi

Gesendet: Donnerstag, 10. Februar 2011 14:11
An: nRoute
Betreff: [nRoute] Re: NEW FEATURE: Application Tombstoning and Cascading
State Management

Hi Gerhard, I'm not looking into designer issues yet - will do so,

Rishi Oberoi

unread,
Feb 10, 2011, 8:14:00 AM2/10/11
to nRoute
I don't think that's true as none of navigation containers re-use an
instance of a view - they are always regenerated.
Rishi

On Feb 10, 2:20 pm, "Gerhard Kreuzer" <gerhard.kreu...@liftoff.at>
wrote:

Rishi Oberoi

unread,
Feb 10, 2011, 8:17:01 AM2/10/11
to nRoute
This was added with check-in # 57243, but always pls get the latest.
Also note this is under nRoute5 folder.
Rishi

On Feb 10, 4:02 pm, "Gerhard Kreuzer" <gerhard.kreu...@liftoff.at>
wrote:

Gerhard Kreuzer

unread,
Feb 10, 2011, 8:23:31 AM2/10/11
to nro...@googlegroups.com
Hi Rishi,

I just have a button on the left side and a StatefulNavigationContainer on
the right side.
After putting all together and overriding OnInitialize and ... putting
Debug.Print-statements inside just to have some list, how my app is working,
I found, that every click on the same button fires all that stuff, which may
include complex de/rehydrating, maybe nested, also if there is no change of
the content of the StatefulNavigationContainer, because the correct view is
there, and some silly user (called Gerhard) just clicking the button for no
reason (like a monkey).

With best regards

Gerhard

-----Ursprüngliche Nachricht-----


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von
Rishi Oberoi

Gesendet: Donnerstag, 10. Februar 2011 14:14
An: nRoute
Betreff: [nRoute] Re: REQUEST: Little performance enhancement of containers

Gerhard Kreuzer

unread,
Feb 10, 2011, 8:24:36 AM2/10/11
to nro...@googlegroups.com
Thanks, will do asap, sorry, just sleeping than working ...

-----Ursprüngliche Nachricht-----


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von
Rishi Oberoi

Gesendet: Donnerstag, 10. Februar 2011 14:17
An: nRoute
Betreff: [nRoute] Re: ISupportNavigationViewState

Gerhard Kreuzer

unread,
Feb 10, 2011, 1:53:13 PM2/10/11
to nro...@googlegroups.com
Hi Rishi,

Here you see, whats happen, if some silly user (like me) start clicking the
same button over and over. Behind the scenes, the whole (maybe complex)
de/rehydration is triggered, but just for nothing.

With best regards

Gerhard

-----Ursprüngliche Nachricht-----


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von
Rishi Oberoi

Gesendet: Donnerstag, 10. Februar 2011 14:14
An: nRoute


Betreff: [nRoute] Re: REQUEST: Little performance enhancement of containers

I don't think that's true as none of navigation containers re-use an

Something to polish.JPG

Gerhard Kreuzer

unread,
Feb 11, 2011, 2:50:53 AM2/11/11
to nro...@googlegroups.com
Hi,
 
I think, I didn't get this with checkout set 57081.
Next set I tried was 57381, and now it appears out of nothing. I just update the references, and didn't made any change to my app's code.
 
Rishi, maybe you can tell us shortly, which changes were made between this two versions, especially add/change references, maybe we can solve it quickly.
 
With best regards
 
Gerhard


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Adrian Hara
Gesendet: Donnerstag, 10. Februar 2011 08:43
An: nro...@googlegroups.com
Betreff: RE: [nRoute] NEW FEATURE: Application Tombstoning and Cascading State Management

Rishi Oberoi

unread,
Feb 15, 2011, 5:58:54 AM2/15/11
to nro...@googlegroups.com
Gerhard, you can have a look at the ChangeLog.txt to see what has changed - anyway, one of the changes to references was that I added a reference to System.Xml.Serialization and removed reference to System.Runtime.Serialization(.) Note this change may or may not be permanent.

Rishi

Adrian Hara

unread,
Feb 20, 2011, 4:09:39 PM2/20/11
to nro...@googlegroups.com

Hey,

 

I’m not sure I understand how tombstoning fits into all of this and how ISupportNavigationViewState is supposed to be used.

 

Specifically, I have the following questions:

1.    Is nRoute now aware of tombstoning events? Do we have to use the ApplicationFrameContainer for this to work?

2.    If 1 is true J, I don’t understand how view-models get to persist/restore their state for tombstoning. Does nRoute now call ISupportNavigationState methods also when tombstoning/rehydrating? Or do we have to somehow involve the views into the process and they have to implement ISupportNavigationViewState?

 

Or maybe a small example would help?...

 

Thnx,

Adi

Freundliche Grüsse / Best regards

Adrian Hara
Cloud Developer
LinkedIn 


coresystems ag
Villa im Park | Dorfstrasse 69
5210 Windisch | Switzerland


Phone +41 56 500 22 22
Fax +41 56 444 20 50
Infoline +41 848 088 088
www.coresystems.ch
www.coresuite.com
follow us on
twitter

Visit us at CeBIT:
SAP Partner Booth: Hall 5, Booth A18
Cloud Computing: Hall 4, Booth A58
OS X Business Park: Hall 2, Booth A20
Microsoft Booth: Hall 4, Booth P47

The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and / or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Gerhard Kreuzer

unread,
Feb 20, 2011, 5:25:30 PM2/20/11
to nro...@googlegroups.com
Hi Adrian,
 
just will also need this and diving into it.
 
The bad new is, that you have to implement ISupportNavigationViewState as far as I can see. I think about to do this in a sample, but this sounds easier than it would be.
 
Lets think about an input mask with 10 text boxes or so, this gives a lot of code. I personally stop thinking about that, as I don't find a easy way to get out the position of the caret. And its also not so easy to find out, which box has the focus, just before the mask was frozen. And I don't want to have a lot of code in the code behind files. And I dont want to make all this more than once, if I want support more than one UI technology.
My WPF knowledge is very basic, so I start thinking about a gerenic way to handle this, but not within the next weeks. Sorry.
 
Thanks again for the link to the RX tutorials, were essentially to find a solution for my problems.
 
With best regards
 
Gerhard


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Adrian Hara
Gesendet: Sonntag, 20. Februar 2011 22:10
An: nro...@googlegroups.com
Betreff: RE: [nRoute] NEW FEATURE: Application Tombstoning and Cascading State Management

Rishi Oberoi

unread,
Feb 23, 2011, 4:42:00 AM2/23/11
to nro...@googlegroups.com
Hi Adrian, well the idea is ISupportNavigationViewState gives you a way to save and restore the internal state of a navigation container, so essentially a navigation container will save and extract all that it needs to work - like where it is at, its navigation history, navigation state etc. And so off the ApplicationFrameContainer, you can get the one value that you need to provide to tombstoning. 

Now, I had said tombstoning can be achieved for free, and that would be possible because in wp7 the nRouteApplicationService type inherits from PhoneApplicationService - so it has access to the tombstoning events. In fact, its also somewhat possible to create your own tombstoning infrastructure such that you can resume even when not coming through the back-stack - but that's not that straightforward, still doable. 

Lastly, yes for the view to save its state it needs to implement ISupportNavigationViewState - see my post about it here http://groups.google.com/group/nroute/browse_thread/thread/1b56674f78341c89

Cheers,
Rishi

Rishi Oberoi

unread,
Feb 23, 2011, 4:51:33 AM2/23/11
to nro...@googlegroups.com
Gerhard you are right, we need to implement ISupportNavigationViewState in the view ourselves. Now, it's entirely possible to save/restore caret position and focus etc - however, from a UX perspective I don't think you need to get every visual-cue back to where it was. The bigger idea should be to give the user a sense of continuity and so depending on the context things like the scroll-position might be important or restoring the specified search-text might be relevant. Also the alternate to a manual/intelligent saving of the visual-state would be to serialize the entire visual-tree, and that I'll assure you will be worse of bet.

Rishi

Gerhard Kreuzer

unread,
Feb 23, 2011, 5:17:58 AM2/23/11
to nro...@googlegroups.com
Hi Rishi,
 
yes, if you were in one application, thats correct, because you make a step and after you go back, you do that for special reasons.
 
But I have an app, where more tasks were running in parallel and the user sometimes has to switch over interrupted by some async events, like a telephone call. After done this, he wants to switch back and try to continue just were he was interrupted.
 
So some layout like a modern browser using tabs will be perfect for me.
 
Maybe, I can use a Tab control as the top most (relevant) control and just place StatefulContainers on each tab page. As far as I saw, the VM behind a container was still preserved, even when other views coming into focus.
 
So lets think about that like an app with more than one shell ...
 
Thanks for the answer.
 
With best regards
 
Gerhard


Von: nro...@googlegroups.com [mailto:nro...@googlegroups.com] Im Auftrag von Rishi Oberoi
Gesendet: Mittwoch, 23. Februar 2011 10:52
An: nro...@googlegroups.com
Betreff: Re: AW: [nRoute] NEW FEATURE: Application Tombstoning and Cascading State Management

Rishi Oberoi

unread,
Feb 23, 2011, 5:42:04 AM2/23/11
to nro...@googlegroups.com
If you need MDI type interface then I highly highly recommend Chronos - see http://chronoswpf.codeplex.com/

It's built upon nRoute, and is maintained by Carlos Guzmán - a member of this group.

Rishi
Reply all
Reply to author
Forward
0 new messages