0

I have a System.Drawing.Region object with the GetBounds() method returning

{X = 0.0 Y = 0.0 Width = 120.0 Height = 120.0}

However when I execute the Exclude() method with a rectangle:

region.Exclude(New System.Drawing.Rectangle(60, -20, 100, 160))

I would expect the Region.GetBounds method to return

{X = 0.0 Y = 0.0 Width = 60.0 Height = 120.0}

instead the Exclude() call appears to do nothing at all. Similarly with the Intersect() method

region.Intersect(New System.Drawing.Rectangle(60, -20, 100, 160))

I would expect to see

{X = 60.0 Y = 0.0 Width = 60.0 Height = 120.0}

but again there is no change. Is this correct?

Edit: Specific context

I am working with the OnPaintBackground() method on a larger project in the direction of a base Control with general transparency: What is a general solution to creating a transparent control?

Protected Overrides Sub OnPaintBackground(pevent As System.Windows.Forms.PaintEventArgs)
    Dim initialClip As Region = pevent.Graphics.Clip

    'Develop list of underlying controls'
    Dim submarinedControls As New List(Of Control)
    For Each control As Control In Parent.Controls.ToArray.Reverse
        If control IsNot Me AndAlso control.Visible AndAlso Me.ClientRectangle.IntersectsWith(control.RelativeClientRectangle(Me)) Then : submarinedControls.Add(control)
        Else : Exit For
        End If
    Next

    'Prepare clip for parent draw'
    pevent.Graphics.Clip = New Region(initialClip.GetRegionData)
    For Each control As Control In submarinedControls
        pevent.Graphics.Clip.Exclude(control.RelativeClientRectangle(Me))
    Next

    ...
End Sub

At the 'Prepare clip for parent redraw' section, after the initial clip has been recreated, its bounds are as specified. The next step is to exclude any underlying controls and only paint the areas where this control interacts directly with the background of the parent control. The exclude method here I can see is receiving the larger rectangle as its argument (as a Watch), but after the Exclude occurs, nothing about the clip's bounds changes.

Edit: Possible Resolution

It appears the Graphics.Clip region is managed by the Graphics object and is immutable. Replacing the exclusion snippet with the following yields all expected results:

    'Prepare clip for parent draw'
    Dim parentClip As System.Drawing.Region = New System.Drawing.Region(initialClip.GetRegionData)
    For Each Control As Control In submarinedControls
        parentClip.Exclude(Control.RelativeClientRectangle(Me))
    Next
    pevent.Graphics.Clip = parentClip

RelativeClientRectangle():

<Runtime.CompilerServices.Extension()>
Public Function RelativeClientRectangle(control As System.Windows.Forms.Control, toControl As System.Windows.Forms.Control) As System.Drawing.Rectangle
    Return New System.Drawing.Rectangle(control.RelationTo(toControl), control.Size)
End Function

RelativeTo():

<Runtime.CompilerServices.Extension()>
Public Function RelationTo(control As System.Windows.Forms.Control, toControl As System.Windows.Forms.Control) As System.Drawing.Point
    Return control.PointToScreen(New Point(0, 0)) - toControl.PointToScreen(New Point(0, 0))
End Function
Community
  • 1
  • 1
J Collins
  • 2,106
  • 1
  • 23
  • 30
  • Works fine when I try it. But I can't see what the original region looks like and what kind of Graphics context you use. Post code that reproduces the problem. – Hans Passant Aug 22 '12 at 15:26
  • I have added my specific context. I am working with graphics transforms also though I can't imagine this influencing the Exclude method on the Region referenced by the graphics object. – J Collins Aug 22 '12 at 15:47
  • Not sure. But Clip is not initialized at the start of the OnPaintBackground() override. It is "infinite". Add `Dim rc = initialClip.GetBounds(pevent.Graphics)` to see that. – Hans Passant Aug 22 '12 at 16:02
  • I have broken just after initialClip is assigned and its GetBounds(pevent.Graphics) is finitely sized, {0, 0, 120, 120}, under what circumstances is it infinite? – J Collins Aug 22 '12 at 17:50

1 Answers1

0

While I cannot be certain, all work seems to agree with my final edit that Graphics.Clip is managed more strictly than an orphan region. The observed behaviour is completely resolved when preparing a region offline for modification.

J Collins
  • 2,106
  • 1
  • 23
  • 30