2009-06-07 4 views
6

Я хочу бесшовно нарисовать кучу разноцветных прямоугольников в WPF. То есть, я хочу поместить кучу прямоугольников от края до края и не иметь промежутков между ними.Плитка прямоугольников в WPF

Если все выровнено по пикселям, это отлично работает. Но я также хочу поддерживать произвольное масштабирование, и в идеале я не хочу использовать SnapsToDevicePixels (потому что это ухудшит качество, когда изображение будет увеличено). Но это означает, что мои Rectangles иногда визуализируются с пробелами. Например:

<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> 

Если ScaleX в ScaleTransform является 1, то Прямоугольники совмещаются легко. Когда он равен 0,5, между ними есть темно-серая полоска. Я понимаю, почему - комбинированные полупрозрачные граничные пиксели не объединяются, чтобы быть непрозрачными на 100%. Но я хотел бы исправить это.

Я всегда мог бы просто совместить прямоугольники, но я не всегда буду знать, какие шаблоны они будут (это для игры, которая в конечном итоге будет поддерживать редактор карт). Кроме того, это может вызвать артефакты вокруг области перекрытия, когда вещи были увеличены до в (если бы я не подрезал углы на нижней части, что очень тяжело, и все еще вызывает проблемы в углах).

Есть ли способ объединить эти прямоугольники в единую комбинированную «форму», которая делает рендеринг без внутренних зазоров? Я играл с GeometryDrawing, что делает именно это, но тогда я не вижу способа рисовать каждую RectangleGeometry с помощью разноцветной кисти.

Есть ли какие-либо другие способы получить фигуры, чтобы плавно перемещаться под произвольным преобразованием, не прибегая к SnapsToDevicePixels?

+0

Поскольку у меня есть та же проблема, я хотел спросить, нашли ли вы решение. – Jens

ответ

2

Вы можете использовать рекомендации (см. GuidelineSet on MSDN) и переопределить методы OnRender Rectangles, чтобы их границы совпадали с границами пикселей устройства. WPF использует рекомендации для определения того, можно ли привязать чертежи и где их можно привязать.

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

Похоже, что Microsoft тоже знает об этой проблеме - WPF 4.0 is expected to feature Layout Rounding, которая, like the version in Silverlight, округляет нецелые значения на проходе рендера, когда включено закругление макета.

0

Я думаю, что пробелы не являются фактическими пробелами, а штрихом, который окрашен. Когда вы уменьшаете масштаб, вы просто уменьшаете ход до точки, где он больше не виден. Я попытался нарисовать штрих в цвете прямоугольника, который отлично работает в любом масштабе.

 
&ltPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Background="Black"> 
    &ltCanvas SnapsToDevicePixels="False"> 
    &ltCanvas.RenderTransform> 
     &ltScaleTransform ScaleX="0.5" ScaleY="0.5"/> 
    </Canvas.RenderTransform> 
    &ltRectangle Canvas.Left="25" Width="100" Height="100" Fill="#CFC" Stroke="#CFC"/> 
    &ltRectangle Canvas.Left="125" Width="100" Height="100" Fill="#CCF" Stroke="#CCF"/> 
    </Canvas> 
</Page> 
+0

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

Смежные вопросы