WP7 Elements: When to Install VisualState after Tombstone Recovery?
My question is simple: WHEN (on which event?) Can I be sure that the control is fully loaded and has its states and templates?
Why am I asking:
I am trying to restore the state of my own WP7 element after tombstone restore. This control looks like a weekly calendar. In this calendar, you can select many items displayed as colored rectangles.
If I select any of these and then go to the tombstone and return to the page, it seems to me that my control has forgotten which is selected Rectangles
. In fact, he did NOT forget about the data itself, but Rectangles
forgot his chosen state.
After tombstone recovery, I'll try to select Rectangles
by setting them VisualState
to "Selected" (which works in any other scenario). I found out that it is failing because it VisualStateManager
cannot find the state "Selected"
.
I know this is tricky because when returning from a tombstone, the controls are not built exactly the same as in any "normal" case. (for example, Bindings
and Templates
do not apply in the same order). But until now, I could always trust that when FrameworkElement.Loaded
I got fired, I had the controls ready. Now it seems VisualState
not. (I tried to set the state from an event handler Loaded
, but the results are the same VisualStateManager.GoToState
returned from false
.)
What else can I do?
source to share
It's complicated! I also ran into issues where UI events fire before the UI itself is fully constructed, see this blog post for an example . My general approach to this is to handle an event LayoutUpdated
that fires every time the visual tree is updated. You will find that this event fires multiple times, both before and after the event Loaded
.
When the event fires LayoutUpdated
, you can check if the visual state change has triggered, if so, no longer handle the event. If not, keep trying!
Within the loaded event, try the following:
// try to set the state
if (VisualStateManager.GoToState(myControl, "myState") == false)
{
// if failed, wait for the next LayoutUpdated event
EventHandler updateHandler = null;
updateHandler = (s, e2) =>
{
if (VisualStateManager.GoToState(myControl, "myState") == false)
{
myControl.LayoutUpdated -= updateHandler;
}
};
myControl.LayoutUpdated += updateHandler;
}
source to share