Прямоугольная мозаика в WPF
Я хочу, чтобы в WPF я разложил несколько разноцветных прямоугольников. То есть я хочу поставить кучу прямоугольников от края к краю, а между ними не должно быть пробелов.
Если все выровнено по пикселям, это работает нормально. Но я также хочу поддерживать произвольное масштабирование, и в идеале я не хочу использовать SnapsToDevicePixels (потому что это ухудшит качество, когда изображение будет уменьшено). Но это означает, что мои прямоугольники иногда отображаются с пробелами. Например:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Black">
<Canvas SnapsToDevicePixels="False">
<Canvas.RenderTransform>
<ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
</Canvas.RenderTransform>
<Rectangle Canvas.Left="25" Width="100" Height="100" Fill="#CFC"/>
<Rectangle Canvas.Left="125" Width="100" Height="100" Fill="#CCF"/>
</Canvas>
</Page>
Если ScaleTransform ScaleX равен 1, то прямоугольники соединяются без проблем. Когда это 0,5, между ними появляется темно-серая полоса. Я понимаю, почему - комбинированные полупрозрачные краевые пиксели не объединяются, чтобы быть непрозрачными на 100%. Но я бы хотел, чтобы это исправить.
Я всегда мог просто наложить прямоугольники, но я не всегда буду заранее знать, в каких шаблонах они будут (это для игры, которая в конечном итоге будет поддерживать редактор карт). Кроме того, это может привести к появлению артефактов вокруг области перекрытия при увеличении масштаба (если только я не делал наклонные углы на области перекрытия, что является огромной работой и по-прежнему вызывает проблемы на углах).
Есть ли какой-нибудь способ, которым я могу объединить эти прямоугольники в одну объединенную "фигуру", которая рендерится без внутренних пробелов? Я поигрался с GeometryDrawing, которая делает именно это, но потом я не вижу способа рисовать каждую RectangleGeometry кистью разного цвета.
Существуют ли другие способы беспрепятственного формирования фигур при произвольном преобразовании, не прибегая к SnapsToDevicePixels?
2 ответа
Вы можете рассмотреть возможность использования рекомендаций (см. GuidelineSet на MSDN) и переопределения методов OnRender прямоугольников, чтобы их границы совпадали с границами пикселей устройства. WPF использует руководящие принципы, чтобы определить, нужно ли и где делать рисунки.
Внутренне, это именно то, что SnapsToDevicePixels использует для обеспечения соответствия объектов пикселям устройства, но, разместив указатели вручную, вы сможете контролировать, когда применяется поведение привязки, а когда - нет (например, когда ваше изображение масштабируется все В этом случае вы можете избегать рисования руководящих принципов или только рисовать руководящие указания, если ваши фигуры лежат рядом с другими фигурами, и полагаться на сглаживание WPF, чтобы позаботиться об остальном). Возможно, вы сможете сделать это с прикрепленным свойством, чтобы применить его к любому элементу, хотя, если это только один тип элемента (например, Rectangle), для которого вам нужно это поведение, вероятно, оно не стоит дополнительных усилий.
Похоже, что Microsoft тоже знает об этой проблеме - ожидается, что в WPF 4.0 будет включено округление макета, которое, как и версия в Silverlight, округляет нецелые значения на этапе рендеринга, когда округление макета включено.
Я предполагаю, что промежутки - не фактические промежутки, а нарисованный штрих. Когда вы уменьшаете его, вы просто уменьшаете размер штриха до точки, где он больше не виден. Я попытался нарисовать обводку цветом прямоугольника, который отлично работает в любом масштабе.