如何创建一个在其他控件之上工作的透明控件?
我有一个控件(派生自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对象上,但它实际上是笨拙的,我根本不喜欢这个解决方案(虽然它可能就是我所拥有的)。
编辑2:所以,根据我对.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
会更快,但我没有时间修补它。
在控制下绘制兄弟姐妹是可能的,但它很难看。 下面的代码对我来说效果很好,它扩展了Ed S.链接中给出的代码。 回答 。
可能的陷阱:
这是代码:
if (Parent != null) { float tx = -Left, ty = -Top; // make adjustments to tx and ty here if your control // has a non-client area, borders or similar e.Graphics.TranslateTransform(tx, ty); using (PaintEventArgs pea = new PaintEventArgs(e.Graphics,e.ClipRectangle)) { InvokePaintBackground(Parent, pea); InvokePaint(Parent, pea); } e.Graphics.TranslateTransform(-tx, -ty); // loop through children of parent which are under ourselves int start = Parent.Controls.GetChildIndex(this); Rectangle rect = new Rectangle(Left, Top, Width, Height); for (int i = Parent.Controls.Count - 1; i > start; i--) { Control c = Parent.Controls[i]; // skip ... // ... invisible controls // ... or controls that have zero width/height (Autosize Labels without content!) // ... or controls that don't intersect with ourselves if (!c.Visible || c.Width == 0 || c.Height == 0 || !rect.IntersectsWith(new Rectangle(c.Left, c.Top, c.Width, c.Height))) continue; using (Bitmap b = new Bitmap(c.Width, c.Height, e.Graphics)) { c.DrawToBitmap(b, new Rectangle(0, 0, c.Width, c.Height)); tx = c.Left - Left; ty = c.Top - Top; // make adjustments to tx and ty here if your control // has a non-client area, borders or similar e.Graphics.TranslateTransform(tx, ty); e.Graphics.DrawImageUnscaled(b, new Point(0, 0)); e.Graphics.TranslateTransform(-tx, -ty); } }
我决定手动在父级控件下绘制父级。 这是一篇好文章。
一些建议。 为VB代码道歉。
尽量避免画背景:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) If m.Msg = &H14 Then Return End If MyBase.WndProc(m) End Sub
Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs) Return End Sub
不要调用控件基础绘制方法:
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 'MyBase.OnPaint(e) - comment out - do not call End Sub
这就是诀窍,至少它对我有用:
上述就是C#学习教程:如何创建一个在其他控件之上工作的透明控件?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
protected override void OnPaintBackground(PaintEventArgs e) { //base.OnPaintBackground(e); this.CreateGraphics().DrawRectangle(new Pen(Color.Transparent, 1), new Rectangle(0, 0, this.Size.Width, this.Size.Height)); }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1269716.html