How to draw chess board pattern with Brush on Canvas?


I got Canvas and some Rectangles of different width but same height. I draw Rectangles on Canvas pragramticaly, width calculated in real time when i draw it.

Some of Rectangles have SolidColorBrush but rest should look like chess board:

enter image description here

I tried to do it like this:

private static Brush CreateBrush()
{

    // Create a DrawingBrush
    var blackBrush = new DrawingBrush();
    // Create a Geometry with white background

    // Create a GeometryGroup that will be added to Geometry
    var gGroup = new GeometryGroup();
    gGroup.Children.Add(new RectangleGeometry(new Rect(0, 0, 10, 10)));
    gGroup.Children.Add(new RectangleGeometry(new Rect(10, 10, 10, 10)));
    // Create a GeomertyDrawing
    var checkers = 
        new GeometryDrawing(new SolidColorBrush(Colors.Black), null, gGroup);

    var checkersDrawingGroup = new DrawingGroup();

    checkersDrawingGroup.Children.Add(checkers);

    blackBrush.Drawing = checkersDrawingGroup;

    // Set Viewport and TileMode
    blackBrush.Viewport = new Rect(0, 0, 0.5, 0.5 );
    blackBrush.TileMode = TileMode.Tile;

    return blackBrush; 
}

As far as Rectangles got different size, same DrawingBrush looks different on different Rectangles - its not repeats to fill it, but stretch.

As i understand, the problem is in blackBrush.Viewport = new Rect(0, 0, 0.5, 0.5 ); - i should set diffrent Viewports according to each Rectangle width, but its no acceptable for me. I need to use one brush for all rectangles of different size and texture should look like one picture - same scale for X and Y, but it can repeat many time in one Rectangle

Maybe there is another Brush type or other way to solve this issues?

Fill free to ask, if my post was unclear, also sorry for my english.

add picture for what i need: enter image description here (It's not about width, its about texture fill)


Answers:


The problem is in the Viewport settings, you should set its ViewportUnits to Absolute instead of RelativeToBoundingBox (as by default):

//we have to use a fixed size for the squares
blackBrush.Viewport = new Rect(0, 0, 60, 60);
blackBrush.Viewport.ViewportUnits = BrushMappingMode.Absolute;

Here is an example showing the checkboard using pure XAML:

<Grid>
    <Grid.Background>
        <DrawingBrush TileMode="Tile" Viewport="0,0,60,60" 
                                      ViewportUnits="Absolute">
            <DrawingBrush.Drawing>
                <GeometryDrawing Brush="Black" 
                    Geometry="M5,5 L0,5 0,10 5,10 5,5 10,5 10,0 5,0 Z"/>
            </DrawingBrush.Drawing>
        </DrawingBrush>            
    </Grid.Background>
</Grid>