我有一个控件(派生自System.Windows.Forms.Control),在某些方面需要透明.我已经使用SetStyle()实现了这个:
public TransparentControl() { SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.BackColor = Color.Transparent. }
现在,如果表单和透明控件之间没有控件,则此方法有效.但是,如果在透明控件(这里是用例)下面碰巧有另一个控件,则它不起作用.中间控件不是绘制,但下面的表格确实显示.我可以通过重写CreateParams并设置WS_EX_TRANSPARENT flashg来获得我需要的效果:
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x20; // WS_EX_TRANSPARENT return cp; } }
这里的问题是它确实减慢了控件的绘制速度.控件已经是双缓冲的,所以没有什么可做的.性能受到的打击非常糟糕,这是不可接受的.还有其他人遇到过这个问题吗?我可以找到的所有资源建议使用方法#1,但同样,这在我的情况下不起作用.
编辑:我应该注意到我确实有一个解决方法.子(透明)控件可以简单地将自己绘制到父对象的Graphics对象上,但它真的很笨,我根本不喜欢这个解决方案(虽然它可能就是我所拥有的).
EDIT2:所以,按照我在.NET中透明度如何工作的建议,我在我的用户控件中实现了IContainer接口,其中包含透明控件.我创建了一个实现ISite的类,我将我的子控件添加到UserControl的Components集合中,Container属性在调试器中正确排列,但我仍然没有获得透明效果.有没有人有任何想法?
这只是我编写的一个简单的事情..我发现的唯一问题是当交叉控件更新时它不会更新..
它的工作原理是将一个位于当前控件后面/与之交叉的控件绘制到位图,然后将该位图绘制到当前控件.
protected override void OnPaint(PaintEventArgs e) { if (Parent != null) { Bitmap behind = new Bitmap(Parent.Width, Parent.Height); foreach (Control c in Parent.Controls) if (c.Bounds.IntersectsWith(this.Bounds) & c != this) c.DrawToBitmap(behind, c.Bounds); e.Graphics.DrawImage(behind, -Left, -Top); behind.Dispose(); } }
DotNet中的透明控件是通过让透明控件的容器在透明控件的窗口中绘制自然然后让透明控件自行绘制来实现的.此过程未考虑重叠控制的可能性.因此,您需要使用某种解决方法来使其工作.
在某些情况下,我已经成功进行了复杂的嵌套,但这主要仅适用于快速和脏的位图分层,并且它不能解决部分重叠控件的任何问题.
我发现下面的修改使事情变得更快:
if((this.BackColor == Color.Transparent) && (Parent != null)) { Bitmap behind = new Bitmap(Parent.Width, Parent.Height); foreach(Control c in Parent.Controls) { if(c != this && c.Bounds.IntersectsWith(this.Bounds)) { c.DrawToBitmap(behind, c.Bounds); } } e.Graphics.DrawImage(behind, -Left, -Top); behind.Dispose(); }
我也认为使用this.Width
/ this.Height
而不是Parent.Width
/ Parent.Height
会更快,但我没有时间修补它.