我有一个返回 GetBounds() 方法的 System.Drawing.Region 对象
{X = 0.0 Y = 0.0 宽度 = 120.0 高度 = 120.0}
但是,当我使用矩形执行 Exclude() 方法时:
region.Exclude(New System.Drawing.Rectangle(60, -20, 100, 160))
我希望 Region.GetBounds 方法返回
{X = 0.0 Y = 0.0 宽度 = 60.0 高度 = 120.0}
相反, Exclude() 调用似乎什么都不做。与 Intersect() 方法类似
region.Intersect(New System.Drawing.Rectangle(60, -20, 100, 160))
我希望看到
{X = 60.0 Y = 0.0 宽度 = 60.0 高度 = 120.0}
但同样没有变化。这个对吗?
编辑:特定上下文
我正在一个更大的项目中使用 OnPaintBackground() 方法,朝着具有一般透明度的基本控件方向工作:创建透明控件的一般解决方案是什么?
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
在“为父级重绘准备剪辑”部分,重新创建初始剪辑后,其边界将按照指定的方式进行。下一步是排除任何底层控件,只绘制该控件直接与父控件背景交互的区域。我可以看到这里的 exclude 方法是接收较大的矩形作为其参数(作为 Watch),但是在 Exclude 发生之后,剪辑的边界没有任何变化。
编辑:可能的解决方案
看起来 Graphics.Clip 区域由 Graphics 对象管理并且是不可变的。用以下内容替换排除片段会产生所有预期结果:
'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
相对客户端矩形():
<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
关系到():
<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