Главная » Silverlight » Контейнер Canvas

0

Единственный контейнер, который мы еще не рассмотрели, — Canvas (Холст) — по­зволяет размещать элементы с помощью точных координат. Для мощных форм, управ­ляемых данными, и стандартных диалоговых окон это плохой метод, однако для соз­дания чего-либо нестандартного (например, игровых окон или поверхности рисования диаграмм) холст — незаменимый инструмент. Кроме того, холст — наиболее простой контейнер. Он не содержит сложной логики размещения, управляющей размерами до­черних элементов. Он всего лишь позиционирует элементы согласно заданным коорди­натам с точными размерами.

Для позиционирования элемента на холсте нужно установить подключенные свой­ства Canvas. Left и Canvas. Тор. Свойство Canvas. Left определяет количество пикселей между левыми краями элемента и холста, a Canvas . Тор — между верхними краями эле­мента и холста.

При необходимости можно явно задать размеры элемента с помощью свойств Width и Height. В контейнере Canvas их задают чаще, чем в контейнерах других типов, по­скольку Canvas не обладает собственной логикой размещения. Холст часто использу­ется, когда нужно точно организовать взаимное расположение нескольких элементов. Если не задать свойства Width и Height, элемент сам установит свои размеры, т.е. он автоматически растянется до размеров, необходимых для того, чтобы в нем помести­лось содержимое. При изменении размеров холста размеры и расположение дочерних элементов не изменяются.

Ниже приведена разметка, определяющая холст с четырьмя кнопками.

cCanvas Background="White"> <Button Canvas.Left="10" Canvas.Top="10"

Content="(10,10)"></Button> <Button Canvas.Left="120" Canvas.Top="30"

Content="(120,30)"></Button> <Button Canvas.Left="60" Canvas.Top="80" Width="50"

Height="50" Content=" (60., 80) "></Button> <Button Canvas.Left="70" Canvas.Top="120" Width="100" Height="50" Content="(70,120)"></Button>

</Canvas>

Как и любой другой контейнер, холст может быть вложенным. Это позволяет для ри­сования графического содержимого на части страницы использовать холст, а для выво­да других элементов — другие стандартные контейнеры Silverlight.

Результат показан на рис. 3.16.

Рис. 3.16. Явное позиционирование кнопок на холсте

Последовательность прорисовки

Если элементы перекрываются, можно задать последовательность их прорисовки с помощью подключенного свойства Canvas . ZIndex.

Обычно все добавляемые элементы имеют одно и то же значение ZIndex, равное нулю. При этом они выводятся в последовательности их расположения в коллекции Canvas. Children, которая определяется их последовательностью в разметке XAML. Элементы, объявленные в разметке позже (например, кнопка (70,120) на рис. 3.13), вы­водятся поверх элементов, объявленных раньше (кнопка (60,80)).

Любой элемент можно переместить в последовательности прорисовки, изменив его значение ZIndex. Элемент, обладающий большим значением ZIndex, всегда выводится поверх элемента с меньшим значением ZIndex. Например, заставить кнопку (60,80) вы­водиться поверх кнопки (70,12) можно с помощью следующей разметки.

<Button Canvas.Left="60" Canvas,Top="80" Canvas.ZIndex="1" Width="50" Height="50" Content**" (60, 80) "></Button>

<Button Canvas.Left="70" Canvas.Top="120" Width="100" Height="50" Content**" (70,120) "</Button>

Примечания. Значения Canvas. ZIndex сами по себе не играют никакой роли. На последовательность вывода влияет только их взаимоотношение. Значением ZIndex может быть любое положительное или отрицательное целое число.

Свойство ZIndex особенно полезно, когда позицию элемента в последовательности вывода нужно изменять программно. Для этого необходимо вызвать метод Canvas. SetzIndex () и передать ему два параметра: объект элемента, позицию которого нужно изменить, и новое значение ZIndex. К сожалению, в Silverlight нет методов, эквивалент­ных методам BringToFront () и SendToBack (), поэтому минимальное и максимальное значения индексов приходится отслеживать вручную.

Отсечение

Правила отсечения в контейнере Canvas не совсем интуитивные. В других контей­нерах содержимое ограничивается пространством, доступным в контейнере. Например, если создать панель StackPanel высотой 100 пикселей и разместить на ней высокий столбец кнопок, то не поместившаяся на панели часть столбца будет отсечена снизу. Это правило вполне соответствует здравому смыслу, но контейнер Canvas не подчиня­ется ему. Он выводит на экран все дочерние элементы, даже те, которые выходят за его пределы. Это означает, что в предыдущем примере можно было задать высоту и ширину панели Canvas, равные О пикселям, и это не повлияло бы на результат.

Такое поведение объекта Canvas обусловлено стремлением повысить производитель­ность. Проверка вхождения в заданные границы занимает некоторое время, поэтому вывод дочерних элементов без проверки выполняется быстрее. Однако такое поведение не всегда желательно. Например, в главе 10 рассматривается анимированная игра, в которой используется Canvas. В ней бомбы падают за пределы игровой зоны (хорошо хоть, что не за пределы экрана) и наслаиваются на другие элементы. Как вы понимаете, в правильно разработанном приложении этого не должно быть.

К счастью, в Canvas поддерживается явное отсечение. Разработчик может вручную задать вывод элементов (или частей элементов) только в пределах определенной обла­сти, что аналогично поведению панелей StackPanel и Grid. Единственное неудобство состоит в том, что разработчик должен вручную определить фигуру области отсечения с помощью свойства Canvas. С lip.

Технически свойство Clip (Отсечение) принимает объект Geometry, который под­робнее рассматривается в главе 8. На платформе Silverlight определен ряд производных от Geometry классов для разных типов фигур, включая квадраты и прямоугольники (RectangleGeometry), эллипсы и окружности (EllipseGeometry) и фигуры произвольной формы (PathGeometry). Ниже приведен пример установки области отсечения прямоу­гольником, совпадающим с границами объекта Canvas.

<Canvas x:Name="canvas" Width="200" Height="500" Background="AliceBlue"> <Canvas.Clip> <RectangleGeometry Rect="0,0 200,500"> </RectangleGeometry> </Canvas.Clip>

<Canvas>

В данном примере область отсечения определена как прямоугольник, для которого заданы два утла: верхний левый (О, О) и нижний правый (200, 500). Указанные коорди­наты заданы относительно объекта Canvas, поэтому координаты верхнего левого утла (0, 0) всегда задают совпадение границы области отсечения с границей объекта Canvas. Если изменить их, содержимое будет выведено за пределами Canvas или часть холста будет недоступной для содержимого.

Установка области отсечения в разметке — не всегда наилучшее решение. Оно особенно проблематично, когда размеры объекта Canvas устанавливаются динамиче­ски, чтобы учесть изменяемые размеры родительского контейнера или окна браузера. В этом случае намного эффективнее установить область отсечения программно. Это можно сделать с помощью простого обработчика события, устанавливающего область отсечения при каждом изменении размеров объекта Canvas. Обработчик реагирует на событие Canvas.SizeChanged, генерируемое при первой прорисовке объета Canvas. Следовательно, при этом учитываются начальные параметры области отсечения.

private void canvas_SizeChanged(object sender,

SizeChangedEventArgs e)

(

RectangleGeometry rect = new RectangleGeometry)); rect.Rect = new Rect(0, 0, canvas.ActualWidth,

canvas.ActualHeight) ; canvasBackground.Clip = rect;

}

Подключить обработчик к событию можно следующим образом.

<Canvas x:Name="canvas" SizeChanged="canvas_SizeChanged" Background="AliceBlue">

Подробнее этот метод будет рассмотрен в главе 10 на примере игры, в которой сбра­сываются бомбы.

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

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