Search code examples
wpfgridalignmentpixel

WPF Grid pixel alignment issues


I'm using the WPF Grid to align objects, and ran into a rather glaring issue regarding pixel alignment of columns. I tried to remove as many variables as possible, and managed to show the issue in this code:

<Window x:Class="Test.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100.5" />
        <ColumnDefinition Width="199.5" />
    </Grid.ColumnDefinitions>
    <Border Background="Red">
        <Grid.Column>1</Grid.Column>
    </Border>
    <Border Background="Red">
    </Border>
</Grid>
</Window>

If you run that sample, it's easy to see that there's an issue in the border between the two columns. It's caused, I believe, because WPF simply alpha-blends one column with the background and the other with the result, even though conceptually both columns are in the same Z, so the pixel should be the blending of the sum of their weights and the background.

I understand this is a problematic issue, and naturally I don't intentionally create columns with partial pixel sizes, but the same effect can be easily observed when using star sizes (which I do use a lot).

This issue can be worked around by using the SnapsToDevicePixels property (<Grid SnapsToDevicePixels="True"> instead of <Grid>). this works because WPF has internally-consistent rounding, so both columns snap to the same pixel. However, I hit a related problem which is very similar in vein, to which I couldn't find a solution.

For some reason, when using the Geometry class, I get the same sort of pixel alignment issues, and I this time I didn't find any sort of work-around. It's as if the pixels are rounded, but now the Geometry is snapped one pixel off, leaving a hole 1-pixel-wide hole.

Example code:

<Window x:Class="Test.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid SnapsToDevicePixels="False">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100.5" />
        <ColumnDefinition Width="199.5" />
    </Grid.ColumnDefinitions>
    <Border Background="Red">
        <Grid.Column>1</Grid.Column>
    </Border>
    <Border>
        <Border.Background>
            <DrawingBrush>
                <DrawingBrush.Drawing>
                    <GeometryDrawing Brush="Red">
                        <GeometryDrawing.Geometry>
                            <RectangleGeometry Rect="0,0,1,1"></RectangleGeometry>
                        </GeometryDrawing.Geometry>
                    </GeometryDrawing>
                </DrawingBrush.Drawing>
            </DrawingBrush>
        </Border.Background>
    </Border>
</Grid>
</Window>

Any idea how to get my pixels aligned properly?

EDIT:

Working correctly now after adding a GuidelineSet according to the answer. Working drawing code is:

<DrawingGroup>
    <DrawingGroup.GuidelineSet>
        <GuidelineSet GuidelinesX="0,1" GuidelinesY="0,1"></GuidelineSet>
    </DrawingGroup.GuidelineSet>                
    <GeometryDrawing Brush="Red">
        <GeometryDrawing.Geometry>
            <RectangleGeometry Rect="0,0,1,1"></RectangleGeometry>
        </GeometryDrawing.Geometry>
    </GeometryDrawing>
</DrawingGroup>

Solution

  • I believe you must use a GuidelineSet in the case of a Drawing. There's a good section on how to apply GuidelineSets available here in the SDK.