Главная » Разработка для Windows Phone 7 » Динамические многоугольники Windows Phone 7

0

Как мы видели, если свойство, продублированное свойством-зависимостью, меняется во время выполнения, соответственно меняется и элемент, свойство которого было изменено. Такое поведение обеспечивает обработчик события изменения значения свойства, встроенный в свойства-зависимости.

Некоторые коллекции также будут реагировать на изменения. Классы Collection (Коллекция), наследуемые от PresentationFrameworkCollection (Коллекция инфраструктуры представления), реагируют на изменения, обусловленные добавлением или удалением объекта из коллекции. Уведомление об изменении передается вверх по дереву наследования элементу, включающему коллекцию. В некоторых случаях изменения свойств-зависимостей членов коллекции также формируют уведомления. (К сожалению, все детали процесса нотификации в данном случае скрыты от разработчика приложения.) Класс UIElementCollection, используемый классами Panel в качестве значения свойства Children, наследуется от класса PresentationFrameworkCollection, как и PointCollection в Polyline и Polygon.

Во время выполнения объекты Point могут динамически добавляться или удаляться из PointCollection, что приведет к соответствующим изменениям Polyline или Polygon.

В проекте GrowingPolygons имеется файл MainPage.xaml, в котором создается экземпляр элемента Polygon и задаются значения паре его свойств:

Проект Silverlight: GrowingPolygons Файл: MainPage.xaml (фрагмент)

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Polygon Name="polygon"

Stroke="{StaticResource PhoneForegroundBrush}" StrokeThickness="{StaticResource PhoneStrokeThickness}" /;

</Grid>

После того как сформировано событие Loaded, файл выделенного кода определяет размер панели для содержимого (как и в приложении Spiral) и начинает с получения тех же данных. Но обработчик события OnLoaded (Когда загружен) просто добавляет две точки Points в коллекцию класса Polygon, чтобы определить вертикальную линию. Все остальное происходит при обработке событий Tick класса DispatcherTimer (для использования которого, конечно же, посредством директивы using необходимо подключить пространство имен System.Windows.Threading):

Проект Silverlight: GrowingPolygons Файл: MainPage.xaml.cs (фрагмент)

public partial class MainPage : PhoneApplicationPage {

Point center; double radius; int numSides = 2;

public MainPage() {

InitializeComponent(); Loaded += OnLoaded;

}

void OnLoaded(object sender, RoutedEventArgs args) {

center = new Point(ContentPanel.ActualWidth / 2 – 1,

ContentPanel.ActualHeight / 2 – 1); radius = Math.Min(center.X, center.Y);

polygon.Points.Add(new Point(center.X, center.Y – radius)); polygon.Points.Add(new Point(center.X, center.Y + radius));

DispatcherTimer tmr = new DispatcherTimer(); tmr.Interval = TimeSpan.FromSeconds(1); tmr.Tick += OnTimerTick; tmr.Start();

}

void OnTimerTick(object sender, EventArgs args) {

numSides += 1;

for (int vertex = 1; vertex < numSides; vertex++) {

double radians = vertex * 2 * Math.PI / numSides; double x = center.X + radius * Math.Sin(radians); double y = center.Y – radius * Math.Cos(radians);

Point point = new Point(x, y);

if (vertex < numSides – 1)

polygon.Points[vertex] = point;

else

polygon.Points.Add(point);

}

PageTitle.Text = "" + numSides + " sides";

}

}

Каждую секунду приложение заменяет в коллекции Points класса Polygon все объекты Point, кроме одного. Единственным неизменным остается первый в коллекции Point – это верхний центральный Point. Кроме того, обработчик событий Tick добавляет новый объект в конец коллекции. В результате получаем многоугольник, каждую секунду увеличивающийся на одну грань:

Теперь можете сами проверить, сколько точек необходимо, чтобы многоугольник визуально превратился в круг!

Заметьте, что приложение не пытается изменить свойства X и Y существующего объекта Point коллекции, а полностью заменяет его. Point – это структура, и он не реализует никакого механизма уведомления. У PointCollection нет никакой возможности узнать об изменении свойства одного из Point в коллекции, уведомление обеспечивается только в случае замены объекта Point.

В реальном приложении при внесении большого числа изменений в PointCollection лучше отсоединить его от Polygon. Это предупредит формирование и передачу в Polygon массы уведомлений об изменениях PointCollection. Код будет выглядеть примерно так:

PointCollection points = polygon.Points; polygon.Points = null;

// … вносит изменения в коллекцию точек

polygon.Points = points;

Отсоединение PointCollection осуществляется путем сохранения ссылки на него и задания свойству Points значения null. После внесения всех необходимых изменений PointCollection повторно присоединяется к Polygon, и Polygon перестраивается соответственно новой коллекции точек.

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

  • Комментарии