Главная » Разработка для Windows Phone 7 » Наконечники, соединения и пунктир

0

При отрисовке толстых линий можно задавать, как будут выглядеть их концы. Их называют наконечниками линий («наконечники», как у стрел). Предлагаемые значения для наконечников являются членами перечисления PenLineCap: Flat (Плоский) (по умолчанию), Square (Квадратный), Round (Скругленный) и Triangle (Треугольный). Зададим одно из этих значений свойству StrokeStartLineCap для наконечника в начале линии и свойству StrokeEndLineCap для наконечника в конце линии. И вот как будет выглядеть линия длиной 30 пикселов со скругленным и треугольным наконечниками:

<Grid Background="LightCyan">

<Polyline Points=" 50 100, 300 200, 300 4 00" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Triangle"

/>

</Grid>

Разница между значениями Flat и Square не так очевидна на первый взгляд. Чтобы подчеркнуть ее, следующая разметка обеспечивает отрисовку поверх толстой более тонкой линии с такими же координатами, обозначая с ее помощью геометрическое начало и конец линии:

<Grid Background="LightCyan">

<Polyline Points=" 50 100, 300 200, 300 4 00" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Flat" StrokeEndLineCap="Square"

/>

<Polyline Points=" 50 100, 300 200, 300 4 00" Stroke="Black" />

</Grid>

Наконечник со значением Flat (сверху слева) обрезает линию точно по ее геометрическим размерам. Значение Square продлевает линии на половину ее толщины. Я больше всего люблю скругленные наконечники:

<Grid Background="LightCyan">

<Polyline Points=" 50 100, 300 200, 300 400" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round"

/>

<Polyline Points=" 50 100, 300 200, 300 400" Stroke="Black" />

</Grid>

Как видите, они тоже продлевают линию на половину ее толщины.

Также можно задавать, как будут отрисовываться углы. Для этого предусмотрено свойство StrokeLineJoin, значениями которого являются члены перечисления PenLineJoin. Рассмотрим результат применения значения Round:

<Grid Background="LightCyan">

<Polyline Points=" 50 100, 300 200, 100 300" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" />

<Polyline Points=" 50 100, 300 200, 100 300" Stroke="Black" />

</Grid>

Или значения Bevel (Скос):

<Grid Background="LightCyan">

<Polyline Points=" 50 100, 300 200, 100 300" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Bevel" />

<Polyline Points=" 50 100, 300 200, 100 300" Stroke="Black" />

</Grid>

Или значения Miter (Конус), которое является значением по умолчанию:

<Grid Background="LightCyan">

<Polyline Points=" 50 100, 300 200, 100 300" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Miter" />

<Polyline Points=" 50 100, 300 200, 100 300" Stroke="Black" />

</Grid>

С соединением Miter могут возникать небольшие проблемы. Если линии состыковываются под очень острым углом, конус может быть очень длинным. Например, конус в месте соединения для линий шириной 10 пикселов, пересекающихся под углом 1°, будет более 500 пикселов! Для защиты от таких неприятностей предусмотрено свойство StrokeMiterLimit:

<Grid Background="LightCyan">

<Polyline Points="50 230, 240 240, 50 250" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Miter" />

<Polyline Points="50 230, 240 240, 50 250" Stroke="Black" />

</Grid>

Значение по умолчанию для StrokeMiterLimit – 10 (но оно зависит от половины StrokeThickness), но его можно и увеличить:

<Grid Background="LightCyan">

<Polyline Points="50 230, 240 240, 50 250" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Miter" StrokeMiterLimit="50" />

<Polyline Points="50 230, 240 240, 50 250" Stroke="Black" /:> </Grid>

Рассмотрим две линии: одна толстая, другая тонкая. Тонкая располагается поверх толстой. Обе имеют одинаковые геометрические координаты. Начальная точка – в верхнем левом углу, конечная – в нижнем левом:

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" />

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="Black" />

</Grid>

Линию можно сделать пунктирной. Для этого зададим StrokeDashArray, который обычно включает всего два числа, например, 1 и 1:

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeDashArray="1 1" />

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="Black" />

</Grid>

Это означает, что штрихи и пробелы пунктирной линии будут равны толщине линии (30 пикселов в данном случае). Как видим, наконечники обрабатываются несколько иначе: они отрисовываются или не отрисовываются в зависимости от того, как завершается линия, штрихом или пробелом.

Чтобы увеличить размер штрихов пунктирной линии, увеличиваем первое значение

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeDashArray="2 1" />

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="Black" />

</Grid>

Также есть возможность задать собственные наконечники для штрихов пунктирной линии. Для этого зададим в качестве значения свойства StrokeDashCap один из членов перечисления PenLineCap: Flat (по умолчанию), Triangle, Square или Round (мое любимое):

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeDashArray="2 1" StrokeDashCap="Round" />

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="Black" />

</Grid>

Это вскрывает небольшую проблему. Скругленные наконечники каждого из штрихов увеличивают его длину с каждого конца на половину толщины линии, т.е. теперь штрихи соприкасаются. Исправить это можно, увеличив расстояния между ними:

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeDashArray="2 2" StrokeDashCap="Round" />

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="Black" />

</Grid>

Чтобы сделать пунктир точечным, несомненно, надо использовать наконечники Round. Также сделаем так, чтобы каждая точка отстояла от соседней на ширину точки. Значения StrokeDashArray, задаваемые в этом случае, могут вызвать некоторое недоумение: длина штриха равна 0 и расстояние между соседними штрихами равно 2:

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeDashArray="0 2" StrokeDashCap="Round" />

<Polyline Points="100 100, 380 100,

380 380, 100 380" Stroke="Black" />

</Grid>

Можно задать более двух чисел. Это позволит получить, например, такое сочетание точек и штрихов:

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeDashArray="0 2 2 2" StrokeDashCap="Round" />

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="Black" />

</Grid>

Даже совсем не обязательно задавать четное количество чисел:

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeDashArray="1 2 3" StrokeDashCap="Round" />

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="Black" />

</Grid>

Еще одно свойство, используемое при описании пунктира – StrokeDashOffset. Оно также связано и с толщиной линии. Это свойство позволяет отрисовывать штрихи, начиная с середины, из-за чего первый штрих (в верхнем левом углу) короче остальных:

<Grid Background=MLightCyanM>

<Polyline Points=M100 100, 380

100,

380 380, 100

380"

Stroke="HotPink" StrokeThickness="30"

StrokeStartLineCap="Round"

StrokeEndLineCap="Round"

StrokeLineJoin="Round" StrokeDashArray="2 2" StrokeDashCap="Round" StrokeDashOffset="1" />

<Polyline Points="100 100, 380

100,

380 380, 100

380"

Stroke="Black" />

</Grid>

Или можно начать с пробела:

<Grid Background="LightCyan">

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="HotPink" StrokeThickness="30" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeDashArray=M2 2" StrokeDashCap="Round" StrokeDashOffset="3" />

<Polyline Points="100 100, 380 100, 380 380, 100 380" Stroke="Black" />

</Grid>

Таким точечным пунктиром можно обвести контур эллипса, например:

<Grid Background="LightCyan">

<Ellipse Width="400M Height="400M

HorizontalAlignment="Center" VerticalAlignment=MCenterM Stroke="Red" StrokeThickness=M23.22M StrokeDashArray=M0 1.5" StrokeDashCap="Round" />

</Grid>

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

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

По теме:

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