Элементы управления WP7: когда устанавливать VisualState после восстановления из Tombstone?

Мой вопрос прост: КОГДА (при каком событии?) могу ли я быть уверен, что элемент управления полностью загружен, а также имеет свои состояния и шаблоны?


Почему я спрашиваю:

Я пытаюсь восстановить состояние своего собственного элемента управления WP7 после восстановления из надгробной плиты. Этот элемент управления выглядит как календарь в недельном представлении. В этом календаре вы можете выбрать множество элементов, отображаемых в виде цветных прямоугольников.

Если я выберу любой из них, а затем перейду к надгробию и вернусь на страницу, кажется, что мой элемент управления забыл, какие Rectangles были выбраны. На самом деле, он НЕ забыл сами данные, но Rectangles забыл их выбранное состояние.

После восстановления из надгробной плиты я пытаюсь выбрать Rectangles, установив для их VisualState значение «Выбрано» (что работает в любом другом сценарии). Я обнаружил, что это не удается, потому что VisualStateManager не может найти состояние "Selected".

Я знаю, что это сложно, потому что при возвращении из надгробия элементы управления строятся не так, как в любом «нормальном» случае. (например, Bindings и Templates не применяются в одном и том же порядке) Но до сих пор я всегда мог быть уверен, что когда FrameworkElement.Loaded сработает, мои элементы управления будут готовы. Теперь вроде VisualState нет. (Я пытался установить состояние из обработчика событий Loaded, но результаты те же, VisualStateManager.GoToState возвращает с false.)

Что еще я могу сделать?


person Tenshiko    schedule 22.03.2012    source источник


Ответы (1)


Это сложно! Я также сталкивался с проблемами, когда события пользовательского интерфейса срабатывали до того, как сам пользовательский интерфейс был полностью создан, см. это сообщение в блоге для примера. Мой общий подход к этому заключается в обработке события LayoutUpdated, которое срабатывает каждый раз при обновлении визуального дерева. Вы обнаружите, что это событие срабатывает несколько раз, как до, так и после события Loaded.

Когда срабатывает событие Layoutupdated, вы можете проверить, сработало ли изменение визуального состояния, если да, то больше не обрабатывайте событие. Если нет, продолжайте пробовать!

В вашем загруженном событии попробуйте следующее:

 // 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;
  }
person ColinE    schedule 23.03.2012
comment
Ха! Бесконечно благодарен! Структура моих элементов управления изменилась со вчерашнего дня, но метод работает! :) Еще раз спасибо! - person Tenshiko; 23.03.2012