2009-06-07 43 views
6

Quiero unir perfectamente un grupo de rectángulos de diferentes colores en WPF. Es decir, quiero poner un montón de rectángulos borde a borde, y no tener espacios entre ellos.Rectángulo de rectángulos perfectamente en WPF

Si todo está alineado con los píxeles, funciona bien. Pero también quiero admitir el zoom arbitrario, e idealmente, no quiero usar SnapsToDevicePixels (porque comprometería la calidad cuando la imagen se acerca). Pero eso significa que mis Rectángulos a veces rinden con espacios. Por ejemplo:

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

Si ScaleX del ScaleTransform es 1, entonces los rectángulos encaja a la perfección. Cuando es 0.5, hay una línea gris oscura entre ellos. Entiendo por qué: los píxeles de borde semitransparentes combinados no se combinan para ser 100% opacos. Pero me gustaría una forma de solucionarlo.

Siempre podría hacer que los Rectángulos se superpongan, pero no siempre sabré de antemano en qué patrones estarán (esto es para un juego que eventualmente soportará un editor de mapas). Además, esto causaría artefactos alrededor del área de superposición cuando las cosas se ampliaron forma en (a menos que hice ángulos de corte en bisel en la parte inferior, que es una gran cantidad de trabajo, y todavía causa problemas en las esquinas).

¿Hay alguna manera en que pueda combinar estos rectángulos en una sola "forma" combinada que se renderice sin espacios internos? He jugado con GeometryDrawing, que hace exactamente eso, pero luego no veo una manera de pintar cada RectangleGeometry con un pincel de otro color.

¿Hay alguna otra forma de hacer que las formas se fundan sin problemas en una transformación arbitraria, sin recurrir a SnapsToDevicePixels?

+0

Como tengo exactamente el mismo problema, quería preguntar si ha encontrado una solución. – Jens

Respuesta

2

Puede considerar el uso de directrices (consulte GuidelineSet on MSDN) y anular los métodos OnRender de Rectángulos para que sus límites se alineen con los límites de píxeles del dispositivo. WPF usa pautas para determinar si y dónde tomar dibujos.

Internamente, es exactamente lo que SnapsToDevicePixels utiliza para garantizar que los objetos se alineen con los píxeles del dispositivo, pero al colocar las pautas manualmente podrá controlar cuándo se aplica el comportamiento de ajuste y cuándo no (la imagen se amplía hasta el final, puede evitar las pautas de dibujo, o solo dibujar pautas donde sus formas se encuentran junto a otras formas, y confiar en el anti-aliasing de WPF para encargarse del resto). Usted podría poder hacerlo con una propiedad adjunta para que pueda aplicarlo a cualquier elemento, aunque si solo es un tipo de elemento (por ejemplo, rectángulo) sobre el que necesita este comportamiento, probablemente no valga la pena el esfuerzo extra.

Parece que Microsoft también es consciente de este problema - WPF 4.0 is expected to feature Layout Rounding, que, like the version in Silverlight, redondea los valores no enteros en la pasada Render cuando se ha habilitado el redondeo de la disposición.

0

Supongo que las lagunas no son huecos reales sino el trazo que está pintado. Cuando lo reduces, reduces el trazo hasta un punto en el que ya no es visible. Traté de pintar el trazo en el color del rectángulo que funciona bien en cualquier escala.

 
&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

No es causado por un derrame cerebral: tenga en cuenta que mi ejemplo solo tenía relleno, no derrame cerebral. Al agregar un trazo, probablemente esté haciendo que el rectángulo sea más grande a la mitad del ancho del trazo, lo que solucionaría el problema (si el ancho del trazo fuera lo suficientemente grande), pero causaría artefactos no deseados en las esquinas internas. –

Cuestiones relacionadas