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?

+3


source to share


1 answer


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;
  }

      

+1


source







All Articles