Search code examples
.netwpfxamlsystem.windows.media

Trying to draw using DrawingContext,but when I try calling Close(), a StackOverflowException occurs


I'm trying to draw ~150 GeometryDrawing objects on a Canvas.

I do this by adding them to a DrawingGroup. I Open() the Drawing group, add the GeometryDrawings, draw the group with the DrawingContext and then Close() the DrawingContext. I add the result to a Image.Source and add this to the canvas.

On closing, my App throws a System.StackOverflowException and I can't seem to find out why?

    internal void Draw(List<GameObject> gameObjects, List<Ray> lighting)
    {
        DrawingGroup group = new DrawingGroup();
        List<GeometryDrawing> geometries = new List<GeometryDrawing>();
        geometries.AddRange(Draw(gameObjects));
        geometries.AddRange(Draw(lighting));

        DrawingContext dc = group.Open();
        foreach (GeometryDrawing g in geometries)
        {
            group.Children.Add(g);
        }
        dc.DrawDrawing(group);
        dc.Close();

        Image image = new Image();
        image.Width = 800;
        image.Height = 500;
        DrawingImage di = new DrawingImage(group);
        image.Source = di;

        Canvas.SetTop(image, 0);
        Canvas.SetLeft(image, 0);
        canvas.Children.Add(image);
    }

Solution

  • The reason for the StackOverflowException is that

    dc.DrawDrawing(group);
    

    adds group to its own Children collection, resulting in an infinite recursion.

    You are mixing the ways to populate the Children of a DrawingGroup. Either directly add Drawings to the Children collection or use a DrawingContext to populate the collection, not both at the same time.

    This should work:

    using (var dc = group.Open())
    {
        foreach (var g in geometries)
        {
            dc.DrawDrawing(g);
        }
    }
    

    Or just don't use a DrawingContext at all:

    foreach (var g in geometries)
    {
        group.Children.Add(g);
    }