Процес на поставяне в две стъпки
Всеки панелен обект автоматично използва същия процес в две стъпки за оразмеряване и поставяне на дъщерни елементи. На първия етап се изчисляват размерите на дъщерните елементи и характерните разстояния, а на втория етап се извършва самото разполагане на дъщерните елементи. Двете стъпки са необходими, тъй като панелът трябва да вземе предвид изискванията на всички дъщерни елементи, преди да разпредели наличното пространство.
Можете да добавите код за управление на тези две стъпки, като замените методите MeasureOverride() и ArrangeOverride(), дефинирани в класа Silverlight FrameworkElement. Тези методи заместват логиката на методите MeasureCore() и ArrangeCore(), дефинирани в класа UIElement. Последните два метода не са достъпни за кода на приложението и не могат да бъдат заменени.
Първата стъпка е да се изчисли пространството, необходимо за всеки дъщерен елемент, като се използва методът MeasureOverride(). Въпреки това, дори в метода MeasureOverride(), дъщерните елементи не получават неограничено пространство. Като минимум те са ограничени от наличното пространство за панела. При необходимост те могат да бъдат ограничени още по-строго. Например панел Grid с два пропорционални реда дава на децата си половината от наличната височина. StackPanel дава на първия елемент цялото налично пространство, на втория елемент всичко, което остава след поставянето на първия, на третия елемент всичко, което остава след поставянето на първите два и т.н.
Всяка реализация на MeasureOverride() преминава през колекцията от дъщерни елементи и извиква метода Measure() на всеки от тях. Подава се обект Size, който указва максималното налично пространство за дъщерния контрол. В края на метода MeasureOverride() панелът връща интерваланеобходими за изобразяване на всички дъщерни елементи и желаните размери на елементите.
По-долу е представена основната структура на метода MeasureOverride() без специфичните инструкции за оразмеряване.
защитена отмяна Size MeasureOverride (ограничение на размера)
// Итерация през всички дъщерни елементи
foreach(UIElement елемент в this.Children)
// Изчислете пространството, необходимо за тока
// дъщерен елемент, предмет на ограничения на availableSize
Наличен размер = нов размер (…);
// Сега можем да извлечем исканото
// размер от element.DesiredSize
// Изчисляване на пространството, необходимо за панела; // ще се използва за задаване на // свойството DesiredSize на панела връща нов размер(...);
Методът Measure() не връща стойност. След извикване на метода Measured на дъщерен елемент, исканият размер се предоставя в свойството DesiredSize на дъщерния елемент. Тази информация може да се използва за позициониране на следващите дъщерни елементи и за изчисляване на общото пространство, необходимо за панела.
Извикването на метода Measure() е необходимо за всеки дъщерен елемент, дори ако не планирате да ограничите неговия размер или да приложите неговото свойство DesiredSize. Много елементи не се показват на екрана, докато методът Measure() не бъде извикан върху тях. Ако искате да позволите на дъщерен елемент да заема толкова свободно пространство, колкото иска, предайте обект Size с Double стойности като параметър. Положителност за двете координати (обикновено се използва за ScrollViewer, защото трябва да покрие цялото съдържание). Когато е зададен на PositiveInfinity, дъщерният елемент връща пространството, необходимо за неговото съдържание. В противен случайВ този случай той връща една от двете стойности (по-малката от двете): или пространството, необходимо за съдържанието, или наличното пространство.
В края на процеса на изчисление контейнерът трябва да върне желания размер. За обикновен панел желаният му размер се изчислява въз основа на желаните размери на всеки дъщерен елемент.
Забележка. Можете просто да върнете ограничението, предадено на метода MeasureOverride() като желания размер на панела. На пръв поглед това изглежда като чудесен начин да получите цялото налично пространство, но този метод ще доведе до сериозни проблеми, ако обект Size с Double стойности бъде подаден като една или и двете координати. PositiveInfinity (PositiveInfinity в този случай означава „заемете цялото пространство, което искате“). Безкрайна стойност е разрешена като ограничение, но не е разрешена като размер. Добавката Silverlight няма да може да разбере какви трябва да бъдат размерите на елемента. Освен това не искайте повече място, отколкото ви е необходимо. Допълнителното пространство ще накара следните елементи, поставени след панела, да се преместят надолу, което ще доведе до празно пространство на екрана.
Проницателните читатели вероятно вече са забелязали сходството между методите Measure(), извиквани чрез всеки дъщерен елемент, и методите MeasureOverride(), които дефинират първия етап от обработката на панела. Всъщност методът Measure() изпълнява метода MeasureOverride(). Следователно, ако контейнерите са вложени един в друг, тогава, когато извикате Measure(), ще получите общия размер, необходим за външния контейнер и всички негови деца.
Една от причините, поради които изчисляването на пространството трябва да се извърши на две стъпки, е да се отчетат външните ивици. Прикогато извикате метода Measure(), той получава общото налично пространство, а когато извикате MeasureOverride(), наличното пространство автоматично се намалява, за да се отчетат външните ивици (разбира се, освен ако не е подадена стойност за безкраен размер).
Източник: Макдоналд, Матю. Silverlight 3 с C# примери за професионалисти. : пер. от английски. —- М. : И.Д. Уилям, 2010. - 656 с. : аз ще. — Паралелно. синигер. английски