Search code examples
wpfdrawingcontext

DrawingContext.DrawRectangle to draw a rect


I'm trying to draw a rectangle into an Image:

<Canvas>
    <Image>
        <Image.Source>
            <DrawingImage>
                <DrawingImage.Drawing>
                    <DrawingGroup x:Name="_drawingGroup" />
                </DrawingImage.Drawing>
            </DrawingImage>
        </Image.Source>
    </Image>
</Canvas>

The c# code looks like:

DrawingVisual visual = new DrawingVisual();
using (DrawingContext dc = visual.RenderOpen())
{
    Rect rect = new Rect(new Point(100, 100), new Size(200, 100));
    dc.DrawRectangle(Brushes.Blue, null, rect);
}

this._drawingGroup.Children.Add(visual.Drawing);
this._drawingGroup.Freeze();

As you can see, I intend to draw a rectangle with left top corner (100,100). But it doesn't work as expected - it always paint at (0,0). What's wrong with me?


Solution

  • A DrawingImage aligns its Drawing to the visible Bounds of the Drawing.

    As a workaround you may just add a transparent rectangle with origin at (0, 0). Note also that you don't need a DrawingVisual to create a Drawing:

    drawingGroup.Children.Add(new GeometryDrawing(
        Brushes.Transparent, null,
        new RectangleGeometry(new Rect(0, 0, 1, 1))));
    
    drawingGroup.Children.Add(new GeometryDrawing(
        Brushes.Blue, null,
        new RectangleGeometry(new Rect(100, 100, 200, 100))));
    
    drawingGroup.Freeze();
    

    An alternative to an Image control with a DrawingImage may be a (large enough) Rectangle with a DrawingBrush:

    <Rectangle Width="10000" Height="10000">
        <Rectangle.Fill>
            <DrawingBrush ViewboxUnits="Absolute" Viewbox="0,0,10000,10000">
                <DrawingBrush.Drawing>
                    <DrawingGroup x:Name="drawingGroup" />
                </DrawingBrush.Drawing>
            </DrawingBrush>
        </Rectangle.Fill>
    </Rectangle>
    

    Now you could create you Drawing like intended:

    drawingGroup.Children.Add(new GeometryDrawing(
        Brushes.Blue, null,
        new RectangleGeometry(new Rect(100, 100, 200, 100))));
    
    drawingGroup.Freeze();