Winforms:透明的控件

Windows Forms的绘制框架是基于GDI+。我们知道GDI+是支持透明色的,也就是支持带有alpha的颜色。那为什么绝大部分控件不支持透明的背景颜色呢?这是Winforms受到了Win32 API的限制。

Winforms的所有控件中,只有FormToolStripDropDown支持Opacity属性。当Opacity属性的值为0时,为完全透明;当值为1时,则为完全不透明;当值在01之间时,则显示出半透明的效果。

那么为什么其他控件不能实现透明的效果呢?当我们深入到Winform的内部代码去分析Opacity的内部实现的时候,我们发现透明效果需要控件支持WS_EX_LAYERED。从MSDN http://msdn.microsoft.com/en-us/library/ms632680(VS.85).aspx上我们发现WS_EX_LAYERED不能用于子窗口(Child Window)上。Form不能成为其他窗口的子窗口。而ToolStripDropDown只有在TopLeveltrue的时候Opacity才有效,此时窗口的类型是已经不是子窗口了。因此这两个类型的空间支持Opacity属性。而其他所有空间在创建的时候都用了WS_CHILD类型,都属于子窗口,所以都不可能支持Opacity属性。

如果希望其他空间支持透明的背景颜色,我们除了BackColor的颜色含有alpha信息之外,还需要把ControlStyles.SupportsTransparentBackColorControlStyles.UserPaint设为true。如果ControlStyles.UserPaint为false时,Winforms会调用Windows的函数去绘制控件的背景色。而Windows中很多控件的绘制过程是基于GDI的,而GDI是不支持透明色的。因此如果希望设置透明的背景色,我们必须要把ControlStyles.UserPaint设为true。

我们希望得到背景颜色为透明的TextBox,我们可以自己从TextBox继承出一个类,并在该类的构造函数里调用Control.SetStyle函数把前面两个Style设为true。下面就是参考代码:

public TransparentTextBox()

{

SetStyle(ControlStyles.UserPaint, true);

SetStyle(ControlStyles.SupportsTransparentBackColor, true);

}

此时如果背景颜色的alpha值为0(如Color.Transparent),则该TextBox的背景变成透明的了。

最后值得一提的是,由于Control.UserPainttrue,对有些控件而言Winforms不会自动把控件画出来,我们需要自己负责绘制的全过程。例如在缺省情况下,ListBox中的所有Item就不会画出来,我们需要在它的Paint事件处理器里完成绘制操作。

阅读更多
想对作者说点什么? 我来说一句
相关热词

没有更多推荐了,返回首页