2

我试图强制绘制由具有更高 z 顺序的其他控件引起的控件的隐藏区域,这些控件属于公共父控件的同一 ControlCollection。这个想法是,对于两个重叠的控件,在绘制两个控件中较高的控件时,它会在较低的控件上调用自己的 InvokePaint 和 InvokePaintBackground 方法,同时传入自己的图形,为相交的绘制操作做好准备。

要求澄清问题:更一般地说,我试图根据第二个控件与第一个控件的重叠方式将一个控件的子集绘制到另一个控件的图形表面。

问题的可视化,从左到右,从上到下

我似乎找不到将绘制我感兴趣的区域的变换和剪切区域的排列。我怀疑问题出在 VisibleClippingBounds 似乎在内部引用原始大小或进行一些无法访问的调用以建立可见性并声明基础区域hidden 因此不需要绘制,将 VisibleClipBounds 折叠成一个边长为零的矩形。

这是我觉得应该可以正常工作的代码,但不能:

Dim translation As Point = Control.RelationTo(Me)
Dim intersectionClip As New Region(Control.RelativeClientRectangle(Me))
intersectionClip.Intersect(siblingClip)
pevent.Graphics.Transform = New Drawing2D.Matrix(1, 0, 0, 1, translation.X, translation.Y)
pevent.Graphics.Clip = intersectionClip

InvokePaintBackground(Control, pevent)
InvokePaint(Control, pevent) 'controlPaintEventArgs)

理论:

1)建立下级控制(Control)到这个控制(Me)的相对位置。该点表示一个向量,该向量在此控件上的 (0, 0) 处开始,在下控件上的 (0, 0) 处结束,给出相对位置。

 Dim translation As Point = Control.RelationTo(Me)

2) 从该控件坐标系中下控件矩形的一个区域开始。返回的矩形位于从 RelationTo 调用返回的点处,并且具有下部控件的大小。

Dim intersectionClip As New Region(Control.RelativeClientRectangle(Me))

3) 将该区域与当时已知的底层控件总面积的预先建立的区域相交,以在该控件的坐标中找到该控件的相关绘图区域。

intersectionClip.Intersect(siblingClip)

4) 在相对控制偏移的方向上对图形对象应用平移变换。

pevent.Graphics.Transform = New Drawing2D.Matrix(1, 0, 0, 1, translation.X, translation.Y)

5)应用之前建立的剪辑区域,重要的是在设置变换之后,以确保在变换变换时它不会被修改。

pevent.Graphics.Clip = intersectionClip

6) 使用此控件的 PaintEventArgs 对象在下部控件上引发绘制事件,其中保存的 Graphics 已准备好进行绘制。

InvokePaintBackground(Control, pevent)
InvokePaint(Control, pevent) 'controlPaintEventArgs)

结果是一个黑色的空洞,没有任何东西被绘制,暗示 VisibleClipBounds 已经塌陷到零区域。

4

1 回答 1

0

似乎解决方案是更仔细地查看事件序列并更密切地关注变换对象的设置和重置。

在序列方面,这个策略是完美的,除了在变换之前设置剪辑是解决方案,只要初始变换是正确的。

该解决方案的应用与此论坛上的另一个问题有关,并附有一些上下文的答案:创建透明控件的一般解决方案是什么?.

于 2012-08-24T03:16:53.683 回答