我在使用一个自定义的圆形进度条控件时遇到了一些麻烦。我试图在右下角重叠它们两个。它有一个透明的背景,这显然在WinForms中是显示背景,但对彼此没有影响。
以下是我所看到的:
我一直在研究stackoverflow,并找到了一些答案的人有这个问题与自定义picturebox控件。大多数的解决方案,似乎没有影响的循环进度条控件。一些解决方案,我已经尝试是。
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
我也有自定义控件上允许透明背景的代码。显然,正如我所说,这不会影响重叠控件。
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
stackoverflow上也有一个TransparentControl解决方案,我看到人们在使用它。我已经创建了这个控件,但要么不知道如何使用它,要么它在我的情况下不起作用。以下是该控件的代码。
public class TransparentControl : Panel
{
public bool drag = false;
public bool enab = false;
private int m_opacity = 100;
private int alpha;
public TransparentControl()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.Opaque, true);
this.BackColor = Color.Transparent;
}
public int Opacity
{
get
{
if (m_opacity > 100)
{
m_opacity = 100;
}
else if (m_opacity < 1)
{
m_opacity = 1;
}
return this.m_opacity;
}
set
{
this.m_opacity = value;
if (this.Parent != null)
{
Parent.Invalidate(this.Bounds, true);
}
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | 0x20;
return cp;
}
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle bounds = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
Color frmColor = this.Parent.BackColor;
Brush bckColor = default(Brush);
alpha = (m_opacity * 255) / 100;
if (drag)
{
Color dragBckColor = default(Color);
if (BackColor != Color.Transparent)
{
int Rb = BackColor.R * alpha / 255 + frmColor.R * (255 - alpha) / 255;
int Gb = BackColor.G * alpha / 255 + frmColor.G * (255 - alpha) / 255;
int Bb = BackColor.B * alpha / 255 + frmColor.B * (255 - alpha) / 255;
dragBckColor = Color.FromArgb(Rb, Gb, Bb);
}
else
{
dragBckColor = frmColor;
}
alpha = 255;
bckColor = new SolidBrush(Color.FromArgb(alpha, dragBckColor));
}
else
{
bckColor = new SolidBrush(Color.FromArgb(alpha, this.BackColor));
}
if (this.BackColor != Color.Transparent | drag)
{
g.FillRectangle(bckColor, bounds);
}
bckColor.Dispose();
g.Dispose();
base.OnPaint(e);
}
protected override void OnBackColorChanged(EventArgs e)
{
if (this.Parent != null)
{
Parent.Invalidate(this.Bounds, true);
}
base.OnBackColorChanged(e);
}
protected override void OnParentBackColorChanged(EventArgs e)
{
this.Invalidate();
base.OnParentBackColorChanged(e);
}
}
任何帮助都将不胜感激。这已经让我发疯几个小时了。谢谢:)
**更新1:**我试着使用下面例子中的代码片段。结果是一样的。在圆形进度条之间仍然有空白(如图所示)。
Parent.Controls.Cast<Control>()
.Where(c => Parent.Controls.GetChildIndex(c) > Parent.Controls.GetChildIndex(this))
.Where(c => c.Bounds.IntersectsWith(this.Bounds))
.OrderByDescending(c => Parent.Controls.GetChildIndex(c))
.ToList()
.ForEach(c => c.DrawToBitmap(bmp, c.Bounds));
还是被难住了
**更新2:**我尝试设置前面的循环进度条,将后面的循环进度条作为它在FormLoad中的父进程。这也不起作用。它使它们彼此透明,但切断了顶部循环进度条不在后面边界内的任何部分。
var pts = this.PointToScreen(circularprogressbar1.Location);
pts = circularprogressbar2.PointToClient(pts);
circularprogressbar1.Parent = circularprogressbar2;
circularprogressbar1.Location = pts;
1条答案
按热度按时间vltsax251#
我将给你们几个建议,告诉你们如何继续下去。
从这个基本的透明控件(
TransparentPanel
)开始。这个类是从
Panel
派生的,这是第一个选择:Panel
是继承/扩展此任务的正确控件吗?可能是,也可能不是。例如,一个
Panel
是一个容器。你需要容器的特性吗?容器意味着很多。它继承了ScrollableControl,并且在它的窗口样式中有ContainerControl。它已经有了一个包袱。你可以选择一个
Label
来代替它,它的重量很轻,或者构建一个UserControl。我不认为有一个绝对的"最佳选择"。这取决于这个自定义控件的用途。你需要尝试一下。
要使用此处显示的代码创建旋转效果,您需要如下所示的
TransparentPanel
控件,它的工作方式与在标准控件的表面上绘制不同。这个控件在绘制的形状中生成了某种"持久性",这在使用另一种类型的控件作为画布时是不存在的(也就是说,如果不对其进行大量调整)。
在这里,ControlStyles.SupportsTransparentBackColor被显式设置,
Panel
类已经支持了这个设置,但还是指定了它,因为它给出了这个自定义控件的概念,只是为了在它的构造函数中读取。此外,
ControlStyles.OptimizedDoubleBuffer
设置为false。这可以防止系统以任何方式干扰控件的绘制。没有 * 缓存 *,自定义控件在失效时会被绘制为新控件。容器窗体最好将其
DoubleBuffer
属性设置为true
,但您可能需要在没有设置的情况下进行测试,以查看是否存在差异。这个自定义控件(不要和
UserControl
混淆)是完全透明的。它不画背景。但是你可以在它的表面上画任何东西。使用之前发布的链接:
DoubleDuffering
)Opacity
)Color.Transparent
和DoubleBuffer
)4种不同的方法可以得到相同的结果。选择哪一种取决于上下文/目的地。
CustomControl
,从Toolbox
放到Form
上,没有用新的更改更新。此外,如果您添加或删除属性,则需要删除控件,重新生成一个新控件并将其放到窗体上。
如果你不这样做,你的修改/添加很有可能被完全忽略,你继续测试那些从来没有发挥作用的特性。
(使用最基本的定制
TransparentPanel
)这是用于生成这些图纸的测试代码:
TransparentPanel
类创建新的自定义控件:TransparentPanel
物体跌落到测试表格上transparentPanel1_Paint
和transparentPanel2_Paint
事件处理程序分配给TransparentPanel1
和TransparentPanel2
。btnRotate
,分配btnRotate_Click
处理程序)