Привязка точек в приложениях WPF

Обновлен: Ноябрь 2007

Графическая система WPF использует аппаратно-независимые модули для независимости от разрешения и устройств. Каждая независимая от устройства точка автоматически масштабируется согласно настройке системы dpi (dots per inch — точек на дюйм). Это обеспечивает приложения WPF корректным масштабированием для различных параметров точек на дюйм и автоматически дает приложению поддержку точек на дюйм.

Однако эта независимость точек на дюйм может создать неравномерное отображение края из-за сглаживания. Эти помехи отображения края, обычно отображающиеся смазанными или полупрозрачными, могут появиться, когда положение края попадает в середину точки устройства, а не между его точками. Для решения этой проблемы WPF позволяет осуществить привязку или фиксацию краев объекта в визуальном дереве к точкам устройства через привязку точек, исключая полупрозрачные края, создаваемые сглаживанием.

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

В этом разделе содержатся следующие подразделы.

  • Привязка точек для визуализации сглаживания
  • Правила
  • Точечные изображения
  • Связанные разделы

Привязка точек для визуализации сглаживания

Четкие линии

Без привязки точек отрисованные сглаженные линии могут стать полупрозрачными, если край не попадает между точками устройства. На следующем рисунке показан результат отрисовки сглаженной линии шириной в одну точку, которая попадает в середину точки устройства (слева), а также линия шириной в одну точку, которая попадает между точками устройства (справа).

Отрисовка сглаженной линии.

Сглаженная линия в сравнении с линией из одной точки в высоту.

С привязкой точек сглаженная линия привязывается (или становится фиксированной) к точкам устройства и отображается более четко, исключая полупрозрачность отображения. В следующем примере показано влияние свойства SnapsToDevicePixels на линию в одну точку. Медленное изменение размеров окна вызывает визуальные помехи на непривязанной линии (слева) и фиксированные размеры привязанной линии (справа) по мере их перемещения.

<Page x:Class="PixelSnapping.Lines"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    Title="Lines" Name="linesPage"
    >
  <StackPanel Width="150"  Margin="7" Orientation="Horizontal">
    <!-- Single pixel line with pixel snapping turned OFF.-->
    <Rectangle SnapsToDevicePixels="False"
       Width="45.5" Margin="10" Height="1" Fill="Red"/>
    <!-- Single pixel line with pixel snapping turned ON.-->
    <Rectangle SnapsToDevicePixels="True"
      Width="45.5" Margin="10" Height="1" Fill="Red"/>
  </StackPanel>
  <!-- Background Grid -->
  <Page.Background>
    <DrawingBrush  Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile">
      <DrawingBrush.Drawing>
        <DrawingGroup>
          <GeometryDrawing Brush="White">
            <GeometryDrawing.Geometry>
              <RectangleGeometry Rect="0,0,1,1" />
            </GeometryDrawing.Geometry>
          </GeometryDrawing>
          <GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z " Brush="#CCCCFF" />
          <GeometryDrawing Geometry="M0,0 L0,1 0.1,1, 0.1,0Z" Brush="#CCCCFF" />
        </DrawingGroup>
      </DrawingBrush.Drawing>
    </DrawingBrush>
  </Page.Background>
</Page>
Aa970908.alert_note(ru-ru,VS.90).gifПримечание.

SnapsToDevicePixels влияет только на элементы, которые выполняются через проход макета. Правила могут задаваться в Drawing с помощью DrawingGroup свойства GuidelineSet объекта. Чтобы вручную установить правила Visual, создайте новые правила при помощи свойств VisualYSnappingGuidelines и VisualXSnappingGuidelines.

Привязка точек увеличивает резкость только у горизонтальных и вертикальных линий и не влияет на диагональные линии.

Примыкающие объекты

Сглаживание также может вызывать визуальные помехи в том случае, когда границы между объектами соприкасаются, и прилегающий край нечетко выравнивается между строками или столбцами точек устройства. Сглаживание может размывать границу основным цветом фона, создавая эффект проникновения, благодаря которому граница между каждым объектом отображается прозрачной. На следующем рисунке демонстрируется эффект проникновения.

Смежные объекты с эффектом проникновения.

Просматривание фона между примыкающими объектами.

Если включена привязка точек, смежные границы привязываются к точкам устройства для удаления эффекта проникновения. В следующем примере показано влияние свойства SnapsToDevicePixels на смежные объекты. Медленное изменение размеров окна отображает эффект проникновения на непривязанных прямоугольниках (слева), в то время как привязанные прямоугольники (справа) соприкасаются без визуальных помех.

<Page x:Class="PixelSnapping.Seeping"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    Title="Seeping"
    >
  <StackPanel Orientation="Horizontal" Height="100">
    <Border  
      SnapsToDevicePixels="False"
      Margin="10" BorderThickness="1" BorderBrush="Black" Height="80" Background="White">
      <StackPanel Height="100.0">
        <Rectangle Width="20" Height="20" Fill="Red"/>
        <Rectangle Width="20" Height="20" Fill="Red"/>
        <Rectangle Width="20" Height="20" Fill="Red"/>
        <Rectangle Width="20" Height="20" Fill="Red"/>
      </StackPanel>
    </Border>
    <Border
      SnapsToDevicePixels="True"
        Margin="10" BorderThickness="1" BorderBrush="Black" Height="80" Background="White">
      <StackPanel Height="100.0">
        <Rectangle Width="20" Height="20" Fill="Red"/>
        <Rectangle Width="20" Height="20" Fill="Red"/>
        <Rectangle Width="20" Height="20" Fill="Red"/>
        <Rectangle Width="20" Height="20" Fill="Red"/>
      </StackPanel>
    </Border>
  </StackPanel>
  <!-- Background Grid -->
  <Page.Background>
    <DrawingBrush  Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile">
      <DrawingBrush.Drawing>
        <DrawingGroup>
          <GeometryDrawing Brush="White">
            <GeometryDrawing.Geometry>
              <RectangleGeometry Rect="0,0,1,1" />
            </GeometryDrawing.Geometry>
          </GeometryDrawing>
          <GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z " Brush="#CCCCFF" />
          <GeometryDrawing Geometry="M0,0 L0,1 0.1,1, 0.1,0Z" Brush="#CCCCFF" />
        </DrawingGroup>
      </DrawingBrush.Drawing>
    </DrawingBrush>
  </Page.Background>
</Page>

Обратите внимание, что привязанные прямоугольники не задают в явном виде значение для свойства SnapsToDevicePixels. Значение свойства true в корневом каталоге необходимо задать только для того, чтобы включить это поведение на всех дочерних элементах.

Текст

WPF (Windows Presentation Foundation) всегда создает сглаженный текст, и, если текст статичен, то он будет привязан к точкам. Это помогает увеличить резкость сглаженного текста с помощью помещения глифов непосредственно на точечную сетку, что позволяет отобразить более четкий текст. Однако, когда WPF (Windows Presentation Foundation) обнаруживает любые анимированные движения, например, скроллинг, масштабирование, или анимированное преобразование, привязка точек выключается до завершения движения. После завершения анимации или скроллинга привязка точек медленно включается заново.

Правила

В своей основе привязка точек выполняется согласно правилам. Правила помогают при настройке геометрии по точечной сетке устройства. В большинстве случаев привязка точек с помощью свойства SnapsToDevicePixels обеспечивает нужный результат. Однако это свойство доступно не всегда, особенно в случае использования объектов Drawing или работы непосредственно с DrawingContext, поэтому для достижения нужной резкости, предоставляемой привязкой точек, необходимо установить правила.

Чтобы установить правила на объектах Drawing и DrawingContext, используется класс GuidelineSet. Этот класс позволяет создавать горизонтальные и вертикальные правила, которые могут быть применены к DrawingGroup или помещены в DrawingContext для последующих команд рисования. В процессе рисования правила указывают, какие линии будут привязаны к точке устройства. Подробные примеры использования GuidelineSet см. в разделе Практическое руководство. Применение GuidelineSet к рисованию.

Также правила можно задать на уровне Visual, изменив коллекции правил по горизонтали и вертикали. Это можно сделать посредством свойств VisualYSnappingGuidelines и VisualXSnappingGuidelines.

Точечные изображения

Из-за независимой природы точек на дюйм объекта WPF, Пользовательский интерфейс, основанный на точечном рисунке, может привести к нежелательным результатам. Сглаженные участки могут размыть изображение из-за проблем с выравниванием отдельных точек. Особенно это актуально для изображений, содержащих высокую частоту изменений, например, строки размером в одну точку со смежными контрастными элементами (такие как чередующиеся черные и белые линии). На следующем рисунке показано различия в качестве выровненного изображения (слева) и изображение с неустановленным выравниванием с точками устройства (справа).

Выравнивание изображения по точкам устройства.

Размытое изображение в связи с отсутствием выравнивания точек устройства.

Общим сценарием для изображений в Пользовательский интерфейс является центровка изображения, представляющего значок внутри другого объекта. Поскольку значки обычно являются маленькими изображениями с высокой частотой изменений, то при внесении поправок в макет приложения может потребоваться убрать визуальные помехи, созданные сглаживанием.

Чтобы правильно разместить изображение по центру, контейнер должен иметь четную ширину и высоту, если ширина и высота точки изображения являются четными. Если изображение имеет нечетную ширину и высоту, то содержащий его элемент также должен иметь нечетную ширину и высоту.

В следующем примере создается два объекта Border, которые содержат Image. Верхняя граница имеет четную ширину и высоту в соответствии с шириной и высотой изображения. Нижняя граница имеет нечетную ширину и высоту.

На следующем рисунке показан результат примера и влияние размера контейнера на изображение.

Изображения, центрованные внутри границ.

<Page x:Class="PixelSnapping.Images"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    Title="Images"
    >
  <StackPanel>
    <!-- Image has a pixel dimension of 144x96. -->
    <!-- Because the image has a even width and height, 
         an even border width and height allows the image to proper center. 
    -->
    <Border HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Height="100">
      <Image HorizontalAlignment="Center" VerticalAlignment="Center" Source="sharpness.png" Stretch="None"/>
    </Border>
    <!-- Image has a pixel dimension of 144x96. -->
    <!-- Because the image has a even width and height, 
         an odd border width and height causes the image to soften. 
    -->
    <Border HorizontalAlignment="Left" VerticalAlignment="Top" Width="201" Height="101">
      <Image HorizontalAlignment="Center" VerticalAlignment="Center" Source="sharpness.png" Stretch="None"/>
    </Border>
  </StackPanel>
  <!-- Grid Background -->
  <Page.Background>
    <DrawingBrush  Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile">
      <DrawingBrush.Drawing>
        <DrawingGroup>
          <GeometryDrawing Brush="White">
            <GeometryDrawing.Geometry>
              <RectangleGeometry Rect="0,0,1,1" />
            </GeometryDrawing.Geometry>
          </GeometryDrawing>
          <GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z " Brush="#CCCCFF" />
          <GeometryDrawing Geometry="M0,0 L0,1 0.1,1, 0.1,0Z" Brush="#CCCCFF" />
        </DrawingGroup>
      </DrawingBrush.Drawing>
    </DrawingBrush>
  </Page.Background>
</Page>

К сожалению, обычная корректировка размера объекта контейнера не гарантирует выравнивания точки устройства. Полный макет приложения может влиять на выравнивание изображения. dpi (dots per inch — точек на дюйм) монитора также влияет на выравнивание изображения. В приведенном выше примере выравнивание изображения будет работать, если монитор настроен на 96 dpi (dots per inch — точек на дюйм). При любом другом значении макет должен быть скорректирован согласно настройкам монитора. По возможности следует избегать высокой частоты изображений в приложениях Windows Presentation Foundation (WPF).

См. также

Основные понятия

Система макета

Ссылки

Image

VisualXSnappingGuidelines

VisualYSnappingGuidelines