我仿迅雷精简版做了一个文件下载工具,但处理背景重绘时遇到一个不透明的问题.
下面这个是图例,其实上面是两个自定义控件,分别是两个任务的控制面板,第一个很透明,因为没有动态重绘背景,第二个红色背景为进度,如果进度为50%,则只绘制横向宽度的50%,上面这个说明已经下载完了。
但动态重绘背景时,所有控件都不透明了。所有控件在设计时都是设为了透明的,请问有解决办法吗?
1.以下是我的代码:
private void TaskViewItem_Paint(object sender, PaintEventArgs e) { if (this.Task.Config.TotalLength > 0) { var progress = (double)this.Task.Config.BytesDownload / (double)this.Task.Config.TotalLength; var rect = new Rectangle(0, 0, (int)((this.Width - 1) * progress), this.Height - 1); e.Graphics.DrawRectangle(new Pen(Color.FromArgb(0x9C, 0xC3, 0xE8)), rect); e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(0xD8, 0xE8, 0xF7)), 1, 1, (int)((rect.Width - 1)), rect.Height - 1); } }
经测试上面这段代码在if条件为真且在初始化时一次性绘制的话,界面非常完美,但后期进度变化了绘制没有效果,出现不了进度的效果,跟没绘一样。跟踪了代码确实会被执行到,但啥反应都没有。
2.我又试了下面这段,这段是写在下载线程事件调用中的,我订阅了下载线程的ProcessChanged事件,这就是上面那张图的效果:
private void task_ProgressChanged(object sender, EventArgs e) { this.Invoke(new MethodInvoker(delegate() {
Graphics g = this.CreateGraphics(); g.FillRectangle(new SolidBrush(Color.Red), 0, 0, (int)(this.Width * ((double)this.Task.Config.BytesDownload / (double)this.Task.Config.TotalLength)), this.Height); })); }
谁能告诉我,怎么在不断重绘背景的情况下让控件背景透明啊?
我发现用方法1的话也是有效果的,就是控件的背景色虽然不变,但确实在绘,因为那几个子控件上会有进度绘过的动画。
如果加一个timer,每秒调用一次this.Refresh()就可以显示,但这样窗体会闪烁,体验很不好。网上说paint里只绘制重叠的部分,也许就是这个原因,有办法让它整体重绘吗?不要闪的。
试试在自定义控件的构造函数里加这句:
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
没有任何效果
哦。是控件背景不透明了,不是自定义控件,“abc.exe”是个标准的lable吗,要不自己写个类MyLable继承Lable,然后在构造函数里加上面那句,再把MyLabe的实例的背景设置为透明
@会长: 那上面每个控件都得设,那就搞死了。
我发现只要我调用一次this.refresh就可以显示透明显示进度条了,用第一种方案,但调用refresh时窗体会闪,郁闷了。。。