Как вы можете «подключиться» к циклу рендеринга WPF, чтобы получить точные результаты от VisualTreeHelper? - PullRequest
0 голосов
/ 29 октября 2009

В настоящее время я пишу пользовательский элемент управления WPF (PARENT), который может содержать несколько дочерних элементов управления (CHILD). Я соединяю элементы управления (РЕБЕНОК) с полилиниями.

Для этого мне нужны местоположения пользовательских элементов управления CHILD. Однако местоположения, которые я получаю от VisualTreeHelper.GetOffset, равны нулю. WPF, вероятно, еще не закончил с определением размера и размещением элементов управления CHILD в памяти, потому что когда я помещаю свой код в обработчик событий OnLoaded моего элемента управления, я получаю правильные расположения для своих дочерних элементов управления.

Это проблема, потому что даже после того, как я загрузил свой элемент PARENT, я все еще хочу иметь возможность добавлять элементы управления CHILD и обновлять мои строки.

Как я сейчас решил эту проблему, переопределив OnRender моих элементов управления CHILD и вызвав событие для моего элемента MAIN, чтобы он знал, что может использовать VisualTreeHelper для получения правильных значений.

Это, однако, означает, что мне нужно будет перерисовать строки, пока последний элемент управления CHILD не закончил рендеринг.

Мое текущее решение больше похоже на обходной путь, чем на решение. Как вы можете «подключиться» к циклу рендеринга WPF, чтобы получить точные результаты от VisualTreeHelper?

1 Ответ

3 голосов
/ 29 октября 2009

Попробуйте переопределить ArrangeOverride или OnRender для родительского элемента управления. WPF выполняет трехэтапный проход макета / рендеринга: сначала он запрашивает элементы управления, сколько места им нужно (измерить), затем он сообщает элементам управления, сколько места они фактически дали всем полученным запросам (упорядочить), а затем фактически рисует все внутри областей, которым был задан каждый элемент управления (render). Для того, чтобы это работало, следует визуальное дерево - корневой элемент (скажем, Window) должен измеряться; он должен попросить своих детей измерить, кто должен спросить своих детей и т. д. вплоть до элементов листа, прежде чем все это начнет возвращаться обратно к корню. Затем начинается проход аранжировки и, наконец, проход рендеринга.

Наблюдая за детским OnRender, вы неявно заявляете, что хотите начать рисовать после того, как измерение и аранжировка произошли, но до того, как родитель начнет рисовать сам. Это можно сделать эквивалентным родительскому OnRender, который включает в себя детский OnRenders. Вы также могли бы сделать это в родительском ArrangeOverride, который оборачивает проход аранжировки детей, в котором (IIRC) фактически устанавливаются значения, к которым обращается VisualTreeHelper.GetOffset (), доступ к которым осуществляется на самом деле.

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

...