WPF и C# - Проблем с GeneralTransform и UIElement.TransformToVisual

Работя с WPF само от няколко месеца, но имам богат опит в WinForm, ASP.NET и Flex. Опитвам се да начертая потребителска контрола, която изглежда като следното ИЗОБРАЖЕНИЕ.

Ние използваме модела MVVM. Когато потребителският контрол се зареди за първи път, всичко се рисува правилно. Контролът се състои от платно. В рамките на платното съществува радиален панел, който ще постави геометрично UIElements, които се добавят. Кръговите възли са изтеглени в радиалния панел. Показаните PolyLines са начертани в платното. Получавам крайните точки на PolyLine, като използвам GeneralTransform и извикване на UIElement.TransformToVisual. Където UIElement в повикването е синият възел в радиалния панел и той се трансформира с радиалния панел. Когато контролата се зареди за първи път, всичко се рисува правилно. Там, където се проваля, е когато моделът MVVM информира, че има актуализация на чертежа.

Когато се опитам да опресня въз основа на системната актуализация, потвърдих, че всичките ми колекции съдържат правилните данни. Така че моделът MVVM се държи както трябва. Въпреки това, когато се опитвам да начертая линиите, извикването ми към TransformToVisual връща точка от 0,0 вместо стойността, която прави по време на зареждането. Това кара моите полилинии да рисуват в горния ляв ъгъл на контролата, вместо да свързват двата възела.

Ето реда на операциите:

1) Зареждането на потребителския контрол ще изгради моите колекции, използвани за изчертаване на контролата. Тези колекции са изградени локално за потребителския контрол и данните идват от основна колекция от информация, която се намира в модела на изгледа. Потребителският контрол регистрира метод за опресняване сам по себе си в съобщение за излъчване на обновяване на потребителския интерфейс.

2) Потребителят се опитва да свърже два сини възела чрез съветник. Конекторът се запазва и съобщението за опресняване на потребителския интерфейс се излъчва.

3) Потребителският контрол извиква метода Refresh. Тук правя цикъл на децата на платното и премахвам PolyLines. Аз също викам radialPanel.Children.Clear. След това изпълнявам същия код, който изгради моите колекции при зареждане. След това обезсилвам потребителския си контрол, за да извикам OnRender. След това OnRender ще се опита да начертае полилиниите, за да свърже възлите. Възлите винаги се поставят правилно в радиалния панел.

4) Действието за свързване на линия се извиква от OnRender. В него използвам GeneralTransform gt = node.TransformToVisual(radialPanel). Това повикване винаги връща 0,0, когато потребителската контрола е „освежена“, но винаги работи при първото зареждане за контролата.

Доста съм сигурен, че проблемът се крие в това как обновявам потребителския контрол въз основа на мрежовото известие. Опитах се да изчистя контролите, след което да извърша отново същите операции за зареждане, но все още нямам успех. Изпълних InvalidateVisual срещу потребителския контрол и се опитах да направя всичко в моя отменен OnRender, но все още нямам успех; 0,0 все още се връща.

Някой има ли идеи какво може да се случи с GeneralTransform? В задънена улица съм и всеки нов път би помогнал.


person Josh    schedule 04.02.2011    source източник


Отговори (1)


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

Проблемът беше, че не налагах MeasureOverride и ArrangeOverride на радиалния панел, преди да се опитам да начертая линиите. Без тези две извикани, възлите са на позиция 0,0 в момента, в който свързвам линиите си. Като ги принуждава да извикат преди да начертаят линиите, TransformToVisual работи правилно.

person Josh    schedule 04.02.2011