ContentPresenter.Loaded не вызывается, когда элемент управления изначально создается как свернутый - PullRequest
0 голосов
/ 19 июля 2011

Возможно, надеемся на чудо, но давайте попробуем: -)

MyControl происходит от Control.Его ControlTemplate содержит

<ContentPresenter ContentTemplate="{TemplateBinding EditorTemplate}"/>

(другие подробности опущены.)

Производные элементы управления предоставляют подходящий EditorTemplate.Например, MyTextControl указывает шаблон, состоящий из TextBox.(Конечно, с правильными привязками.)

Я не буду описывать, что работает (большинство сценариев), а что нет:

Создается свернутый экземпляр MyTextControl.Позже этот контроль становится видимым.Вот что происходит:

  • Создан экземпляр MyTextControl, установлено значение Collapsed
  • Событие MyTextControl.Loaded: на данный момент визуальное дерево содержит MyTextControl без дочерних элементов.
  • В обработчике Loaded я вызываю ApplyTemplate ().В свою очередь, визуальное дерево изменяется на MyTextControl -> ContentPresenter.Вот и все, больше нет детей.
  • Стил в Loaded-обработчике, я назначаю Loaded-обработчик ContentPresenter.
  • Иногда позже элемент управления становится видимым.Его визуальное дерево заполняется внутренними объектами TextBox: Border -> ContentControl -> ContentPresenter -> внутренний TextBoxView.Другими словами, элемент управления просто работает.

Проблема в том, что Обработчик загруженного ContentPresenter не был вызван , т.е. я не могу определить момент, когда элемент управления готов.

Я попробовал альтернативное решение, т.е. вместо форсирования ApplyTemplate () я просто ждал в MyControl.OnApplyTemplate ().Последовательность:

  • Создан экземпляр MyTextControl, установлено значение Collapsed
  • В обработчике Loaded визуальное дерево содержит MyTextControl без дочерних элементов.
  • Элемент управления становится видимым.
  • В OnApplyTemplate () визуальным деревом является MyTextControl-> ContentPresenter.
  • Стил в OnApplyTemplate (), я назначаю обработчик Loaded для ContentPresenter.
  • Остальное как и раньше,Визуальное дерево заполняется внутренними компонентами TextBox (элемент управления работает), но вышеупомянутый обработчик не вызывается.

Кто-нибудь знает способ, как определить момент, когда элемент управления полностью загружен?

Обратите внимание, что я проделал вышеупомянутое с несколькими другими производными от MyControl элементами управления.Для каждого из них работал один из указанных выше сценариев (иногда один, иногда другой), но элемент управления на основе TextBox является первым, в котором я не могу определить момент загрузки.

Также обратите внимание, что эта проблемане происходит, когда элемент управления виден постоянно.

1 Ответ

1 голос
/ 19 июля 2011

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

Принудительное построение шаблона с помощью вызова ApplyTemplate () также не является решением, так как в некоторых случаях это может привести к созданию частичного дерева управления.аналогичные проблемы - его можно вызвать, когда построено только частичное дерево управления.

После подтверждения приведенных выше утверждений я решил попробовать событие LayoutUpdated.Я установил обработчик в OnApplyTemplate () (я пытался использовать последний возможный момент) и исследовал дерево управления.В первом приближении достаточно проверить, есть ли у ContentPresenter дочерние элементы.Если это так, мы скажем, что элемент управления загружен и отмените регистрацию обработчика LayoutUpdated.Можно использовать более изощренный тест, но тривиальный, который я только что описал, работает с широким диапазоном элементов управления.

Изначально я боялся, что решение LayoutUpdated будет неэффективным, но похоже (используя описанную организацию) первый вызов обработчика - это именно то место, где элемент управления «загружен».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...