Search code examples
c#wpfdrawingbrush

WPF pixel gridlines


I'm trying to draw a grid on my canvas in which:

  1. The lines are always one pixel thick
  2. The size of the square tile are expressed in pixel or in other words the distance between each horizontal and vertical lines is in pixels and maybe binded to the code behind so that I can change it at run time.

This is my first attempt, but maybe I'm using the wrong controls.

<Canvas  Panel.ZIndex="0"  x:Name="TileCanvas">
    <Grid Panel.ZIndex="5">
        <Rectangle Width="{Binding ElementName=TileCanvas, Path=ActualWidth}" Height="{Binding ElementName=TileCanvas, Path=ActualHeight}" 
            Stroke="Black" StrokeThickness="0"> 

            <Rectangle.Fill>
                <DrawingBrush ViewportUnits="Absolute" TileMode="Tile">
                    <DrawingBrush.Viewport>
                        <MultiBinding Converter="{StaticResource RectConverter}">
                            <...>
                        </MultiBinding>
                    </DrawingBrush.Viewport>
                    <DrawingBrush.Drawing>
                        <DrawingGroup>
                            <GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z" Brush="Green" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
                            <GeometryDrawing Geometry="M0,0 L0,1 0.1,1, 0.1,0Z" Brush="Green" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
                        </DrawingGroup>
                    </DrawingBrush.Drawing>
                    <DrawingBrush.Transform>
                        <ScaleTransform ScaleX="1" ScaleY="1"/>
                    </DrawingBrush.Transform>
                </DrawingBrush>

            </Rectangle.Fill>

        </Rectangle>
    </Grid>

This solution allows me to vary the size of each tile, but:

  1. I didn't find the way to fix the line thickness to one pixel
  2. When I change the DrawingBrush.Viewport with the converter I do enlarge the tile (Great!) but the thickness of the lines increase (boo).

Solution

  • I had a very similar problem. You can use a single geometry and if you want to avoid thickness increase\decrease you have to express the thickness in terms of the tile width by a ratio like thickness = 1/tileWidth. If you change that size of your tile with a WPF control you can use a converter to update the thickness accordingly.

    <GeometryDrawing Geometry="M10,0 L10,10 0,10 10,10 10,0Z"  Brush="Green" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
        <GeometryDrawing.Pen>
            <Pen Thickness="{Binding ElementName=[TILE SIZE CONTROL VAL], Converter={StaticResource RatioConverter}}"/>
        </GeometryDrawing.Pen>
    </GeometryDrawing>
    
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (1 / (double)value);
    }