我有一个控件(从System.Windows.Forms.Control派生),它需要在某些方面是透明的。我使用SetStyle()实现了这一点:
public TransparentControl()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent.
}
现在,如果窗体和透明控件之间没有控件,则此方法有效。但是,如果在透明控件下面碰巧有另一个控件(这是这里的用例),它就不起作用。中间控件不是draw,但下面的表单确实显示出来了。我可以通过覆盖WARNING Params并设置WS_EX_TRANSPARENT flasg来获得所需的效果,如下所示:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20; // WS_EX_TRANSPARENT
return cp;
}
}
这里的问题是,它 * 真的 * 减慢了控件的绘制速度。该控件已经是双缓冲的,所以没有什么可做的。性能打击是如此糟糕,这是不可接受的。其他人遇到过这个问题吗?我能找到的所有资源都建议使用方法1,但同样,这在我的情况下不起作用。
编辑:我应该注意到我有一个变通办法。子控件(透明的)可以简单地将自己绘制到父控件的Graphics对象上,但它真的很难看,我一点也不喜欢这个解决方案(尽管它可能是我所拥有的全部)。
编辑2:所以,根据我在.NET中如何透明工作的建议,我已经在包含透明控件的用户控件中实现了IContainer接口。我已经创建了一个实现ISite的类,我将我的子控件添加到UserControl的Components集合中,Container属性在调试器中正确排列,但我仍然没有获得透明效果。有人有什么想法吗?
7条答案
按热度按时间7hiiyaii1#
这只是我做的一个简单的事情。我发现的唯一问题是,当交叉控件更新时,它不会更新。
它的工作原理是将当前控件后面/与当前控件相交的控件绘制到位图中,然后将该位图绘制到当前控件。
qltillow2#
DotNet中的透明控件是通过让透明控件的容器在透明控件的窗口中绘制自身,然后让透明控件绘制自身来实现的。这个过程没有考虑到重叠控制的可能性。因此,您需要使用某种变通方法来使其工作。
在某些情况下,我已经成功地处理了复杂的嵌套,但这主要只适用于位图的快速分层,并且不能解决部分重叠控件的任何问题。
dohp0rv53#
我发现下面的修改让事情变得更快:
我还认为使用
this.Width
/this.Height
而不是Parent.Width
/Parent.Height
会更快,但我没有时间去修改它。roejwanj4#
将兄弟姐妹置于控制之下是可能的,但它很丑。下面的代码对我来说工作得相当好,它扩展了Ed S.' answer中链接中给出的代码。
可能的陷阱:
DrawToBitmap
是在.net 2.0中引入的,所以不要指望它能与任何更老的东西一起工作。但即使这样,通过向兄弟控件发送WM_PRINT,也可以实现类似的功能;这就是DrawToBitmap在内部所做的。WS_EX_TRANSPARENT
,它也可能会有问题,因为根据msdn,窗口样式会扰乱绘画顺序。我还没有得到任何控制,使用这种风格,所以我不能告诉。代码如下:
q5lcpyga5#
我决定简单地在我的子控件下手动绘制父控件。Here is a good article.
9fkzdhlc6#
一些建议(为VB代码道歉)。
尽量避免绘制背景:
不要调用控件的基础绘制方法:
tkclm6bt7#
这是一个诀窍,至少对我来说是这样的: