Настройка линий
60WPF --- Графика и анимация WPF --- Настройка линий
Наконечники и стыки линий
При рисовании фигур Line и Polyline можно указать форму начальной и конечной точек линии, используя свойства StrokeStartLineCap и StrokeEndLineCap. (Эти свойства не имеют эффекта в других фигурах, поскольку те замкнуты.)
Изначально свойства StrokeStartLineCap и StrokeEndLineCap установлены в Flat, что означает немедленное завершение линии в ее конечных координатах. К другим возможным вариантам относятся Round (линия мягко скругляется), Triangle (обе стороны линии сводятся в точку) и Square (линия завершается четкой границей). Все эти значения добавляют линии длину — другими словами, они выводят ее за ту позицию, в которой она закончилась бы в противном случае. Дополнительное расстояние составляет половину толщины линии.
Единственное отличие между Flat и Square состоит в том, что линии, завершающиеся как Square, просто на половину толщины длиннее с каждой стороны. Во всех остальных отношениях они выглядят одинаково.
Ниже показаны различные варианты концов линий:
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Polyline Stroke="LightBlue" StrokeThickness="15" StrokeEndLineCap="Flat" SnapsToDevicePixels="True"
Points="10,10 30,0 50,20 90,10 200,10" >
</Polyline>
<TextBlock Grid.Column="1">Flat Line Cap</TextBlock>
<Polyline Stroke="LightBlue" StrokeThickness="15" Grid.Row="1" StrokeEndLineCap="Square" SnapsToDevicePixels="True"
Points="10,10 30,0 50,20 90,10 200,10" >
</Polyline>
<TextBlock Grid.Row="1" Grid.Column="1">Square Line Cap</TextBlock>
<Polyline Stroke="LightBlue" StrokeThickness="15" Grid.Row="2" StrokeEndLineCap="Round" SnapsToDevicePixels="True"
Points="10,10 30,0 50,20 90,10 200,10" >
</Polyline>
<TextBlock Grid.Row="2" Grid.Column="1">Round Line Cap</TextBlock>
<Polyline Stroke="LightBlue" StrokeThickness="15" Grid.Row="3" StrokeEndLineCap="Triangle" SnapsToDevicePixels="True"
Points="10,10 30,0 50,20 90,10 200,10" >
</Polyline>
<TextBlock Grid.Row="3" Grid.Column="1">Triangle Line Cap</TextBlock>
</Grid>
Все фигуры, кроме Line, позволяют изменять вид и форму углов через свойство StrokeLineJoin. Здесь существует три варианта: Miter (значение по умолчанию) использует четкие грани, Bevel обрезает угол в точке сопряжения, a Round — плавно скругляет его. На рисунке можно видеть разницу между ними:
При использовании граней Miter при толстых линиях и очень малых углах может получиться, что угол превышает половину толщины линии. Если вы установите толщину 3, то выступающий угол может в полтора раза превышать толщину линии. В последней линии на рисунке используется большое значение заострения с узким углом.
Пунктирные линии
Вместо рисования скучных сплошных линий на границах вашей фигуры можно использовать пунктирные (dashed) линии — т.е. линии, прерываемые пробелами в соответствии с указанным шаблоном.
При создании пунктирной линии в WPF вы не ограничены определенным набором жестко заданных вариантов. Вместо этого можно выбирать длину сплошного сегмента и длину прерванного сегмента (пробела), устанавливая свойство StrokeDashArray.
Например, рассмотрим следующую линию:
<Polyline Stroke="Blue" StrokeThickness="14" StrokeDashArray="1 2"
Points="10,30 60,0 90,40 120,10 350,10">
</Polyline>
Здесь задана длина сплошного сегмента — 1 и ширина пробела — 2. Эти значения интерпретируются относительно толщины линии. Поэтому если линия имеет толщину 14 единиц (как в данном примере), то сплошная часть будет иметь длину 14 единиц, а ширина пропуска — 28. Линия повторяет этот шаблон на протяжении всей своей длины.
С другой стороны, если поменять местами эти значения, задав их следующим образом:
StrokeDashArray="2 1"
то получится линия с длиной сплошного участка в 28 единиц и шириной пропуска в 14 единиц. На рисунке показаны обе линии. Несложно заметить, что когда сегмент очень толстой линии приходится на угол, он может быть обрезан неровно:
Можно также использовать и нецелочисленные значения. Например, следующее значение StrokeDashArray вполне допустимо:
StrokeDashArray="5 0.2 3 0.2"
Здесь применяется более сложная последовательность — штрих длиной 5x14, затем пробел шириной 0.2x14, за которым идет штрих длиной 3x14 и еще один — длиной 0.2x14. В конце этой последовательности линия повторяет тот же шаблон сначала.
Интересная вещь происходит, когда StrokeDashArray передается нечетное количество значений. Рассмотрим пример:
StrokeDashArray="3 0.5 2"
При рисовании этой линии WPF начинает с линии длиной в 3 толщины, за которой следует пробел в половину толщины линии, за которым идет штрих длиной в 2 толщины. Но когда шаблон повторяется, он начинается с пробела в 3 толщины, за ним идет линия длиной в половину толщины и опять пробел. По сути, пунктирная линия чередует шаблоны между сегментами линии и пробелами.
Если нужно, чтобы шаблон пунктирной линии начинался с его середины, можно применить свойство StrokeDashOffset, которое представляет собой начинающийся с О индекс, указывающий на одно из значений из StrokeDashArray. Например, если установить StrokeDashOffset равным 1 в предыдущем примере, то линия начнется с пробела в половину толщины. Установите 2 — и линия начнется с сегмента в 2 толщины.
И, наконец, можно управлять внешним видом наконечников сегментов линии. Изначально они рисуются как прямой срез, но можно установить значение StrokeDashCap в Bevel, Square и Triangle — смысл этих значений рассматривался в предыдущем разделе. Не забывайте, что все эти настройки добавляют половину толщины линии в конец каждого штриха. Если не принять этого во внимание, можно получить штрихи, которые "наползают" друг на друга. Решение состоит в добавлении ширины пробела, чтобы компенсировать этот эффект.
При использовании свойства StrokeDashCap с линией (но не с фигурой) часто имеет смысл установить StartLineCap и EndLineCap в одно и то же значение. Это сделает внешний вид линии более согласованным.