自绘控件~高手来~~~~~~~~~

TTOJJ 2010-06-18 10:28:15


public partial class banner : Panel
{
public banner()
{
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
// SetStyle(ControlStyles.DoubleBuffer, true);
InitializeComponent();

}

public banner(IContainer container)
{
container.Add(this);

InitializeComponent();

}
public struct colorStruct
{
public Color color;
public int position;

public colorStruct(Color color, int postition)
{
this.color = color;
this.position = postition;
}
}
public List<colorStruct> colorList = new List<colorStruct>();
List<Rectangle> rectangle = new List<Rectangle>();

public event EventHandler CreateList;
//需要的时候修改这里即可
void createList()
{
if (CreateList == null)
{
colorList.Add(new colorStruct(Color.FromArgb(116, 161, 203), 0));

colorList.Add(new colorStruct(Color.FromArgb(107, 168, 215), 50));
colorList.Add(new colorStruct(Color.FromArgb(84, 132, 194), 100));
if (image == null)
{
image = new Bitmap(Width, Height);
}
}
else
{
CreateList(this, null);
}



}
Image image;
Bitmap bitmap = new Bitmap("banner.png");
void createRectangles()
{
GraphicsPath pt = new GraphicsPath();
LinearGradientBrush br;
rectangle.Clear();
if (image != null) { image.Dispose(); }
image = new Bitmap(Width, Height);
Graphics g = Graphics.FromImage(image);
int itemHight = 0;
for (int i = 0; i < colorList.Count - 1; i++)
{
rectangle.Add(new Rectangle(0, itemHight, Width, (colorList[i + 1].position - colorList[i].position) * Height / 100));

itemHight = rectangle[i].Height - 1;

br = new LinearGradientBrush(rectangle[i], colorList[i].color, colorList[i + 1].color, LinearGradientMode.Vertical);
pt.Reset();
pt.AddRectangle(rectangle[i]);
g.FillPath(br, pt);
}
g.DrawImage(bitmap, this.Width - bitmap.Width, this.Height - bitmap.Height);
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
createRectangles();
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.CompositingMode = CompositingMode.SourceOver;
if (colorList.Count == 0)
{
createList();
createRectangles();
}
g.DrawImage(image, new Point(0, 0));
}

}


我想做一个banner~~可是效率非常底,总是时不时的闪一闪,大家帮忙看看,哪里需要改进
...全文
211 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
apk2009 2011-04-12
  • 打赏
  • 举报
回复
提问的人比回答的人还要拽
zzx509 2010-06-18
  • 打赏
  • 举报
回复

//构造中添加一个,在缓冲区绘制
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
if (Width == 0 || Height == 0)
{
//所在窗体最小化
return;
}
createRectangles();
this.Invalidate();
}

上面的OnSizeChanged中最后一句必须有,否则控件随窗体缩放时造成绘制紊乱。
另外要考虑窗体最小化的情况,Width为0会造成new Bitmap(Width, Height)时异常。
如果经过上面的尝试仍有闪烁,SetStyle(ControlStyles.DoubleBuffer, true);那么双缓冲也使用。
dylike 2010-06-18
  • 打赏
  • 举报
回复
1 代码中没有双缓冲相关的语句
2 改用.Backgroundimage而不是直接绘制在控件上
3 绘制到一张图上,然后将这张图设为.BackGroundimage
kolosi 2010-06-18
  • 打赏
  • 举报
回复
OnPaint里面用drawimage,可能是这个引起的问题。
drawimage一般需要8位数的cpu时钟周期,放在onpaint里面不合适。

具体可以用vc做个rdtsc指令的dll,测试一下效率就清楚了。
TTOJJ 2010-06-18
  • 打赏
  • 举报
回复
真是说话不负责任~~哎,伤心
TTOJJ 2010-06-18
  • 打赏
  • 举报
回复
我郁闷啊,我那就是双缓冲啊,,都不看程序就乱说话!!!

哪里不是双缓冲了,高手知道下????


=================================
一般使用双缓冲, 相关的例子你可以找找。

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);


这个顶什么用???我的onpain里是g.DrawImage(image, new Point(0, 0));!!!!
healer_kx 2010-06-18
  • 打赏
  • 举报
回复
嗯,双缓冲是很成熟的手段了。~
xiehuanxie 2010-06-18
  • 打赏
  • 举报
回复
一般使用双缓冲, 相关的例子你可以找找。

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
TTOJJ 2010-06-18
  • 打赏
  • 举报
回复
我顶~!!!
TTOJJ 2010-06-18
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 kolosi 的回复:]
引用 12 楼 ttojj 的回复:
想不changesize不闪烁,要么你让盛放你这个空间的面板doublebuffer了,要么你就不要再onsizechange是重绘,onsizechange是只重绘个方框,onmouseup时再重绘空间。

我哪里有写到重绘了???瞎画,好好看看代码

this.Invalidate();
这个是干嘛的,你猜猜看。
[/Quote]


我服了~~~不讨论那个了

楼主,运行了你的代码,加了 SetStyle(ControlStyles.DoubleBuffer, true) 后reszie没有闪烁的现象啊,只是CPU占用偏高(CPU偏高不知道有什么好办法,即使用11楼的方法)。


问题解决-----你提醒了我,闪烁是因为它嵌套在还没有完善的控件里~~猪头了一回
takemoto 2010-06-18
  • 打赏
  • 举报
回复
楼主,运行了你的代码,加了 SetStyle(ControlStyles.DoubleBuffer, true) 后reszie没有闪烁的现象啊,只是CPU占用偏高(CPU偏高不知道有什么好办法,即使用11楼的方法)。
enderboy520 2010-06-18
  • 打赏
  • 举报
回复
楼主你确定你的是双缓冲吗
不是环冲啥的?


表骂我 我是打酱油的 顺便 LZ请心平气和的求助 表太暴躁了
zoopark 2010-06-18
  • 打赏
  • 举报
回复
学习帮顶
kolosi 2010-06-18
  • 打赏
  • 举报
回复
控件大小直接用改控件的宽和高的话,必定重绘。。。。
kolosi 2010-06-18
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 ttojj 的回复:]
想不changesize不闪烁,要么你让盛放你这个空间的面板doublebuffer了,要么你就不要再onsizechange是重绘,onsizechange是只重绘个方框,onmouseup时再重绘空间。

我哪里有写到重绘了???瞎画,好好看看代码
[/Quote]
this.Invalidate();
这个是干嘛的,你猜猜看。
TTOJJ 2010-06-18
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 cgabriel 的回复:]
如何:手动呈现缓冲图形
http://msdn.microsoft.com/zh-cn/library/ka0yazs1.aspx

楼主的是冒牌双缓冲
[/Quote]

这才是真正的双缓冲,最先是用在dos下的游戏编程中的!!!
TTOJJ 2010-06-18
  • 打赏
  • 举报
回复
你们这么相信doublebuffer?????我晕死啊,你们说下原理~~加了还是一样的,搞什么搞啊,完正的程序都给出来了,都没人运行一下就说doublebuffer~~~!!!!!!


想不changesize不闪烁,要么你让盛放你这个空间的面板doublebuffer了,要么你就不要再onsizechange是重绘,onsizechange是只重绘个方框,onmouseup时再重绘空间。

我哪里有写到重绘了???瞎画,好好看看代码



上面的OnSizeChanged中最后一句必须有,否则控件随窗体缩放时造成绘制紊乱。
另外要考虑窗体最小化的情况,Width为0会造成new Bitmap(Width, Height)时异常。
如果经过上面的尝试仍有闪烁,SetStyle(ControlStyles.DoubleBuffer, true);那么双缓冲也使用。


上面的OnSizeChanged中最后一句必须有,否则控件随窗体缩放时造成绘制紊乱。----啥意思?为什么必须??changeSize之后不会重新调用onPain吗???
另外要考虑窗体最小化的情况,Width为0会造成new Bitmap(Width, Height)时异常。---这句话不错

CGabriel 2010-06-18
  • 打赏
  • 举报
回复
如何:手动呈现缓冲图形
http://msdn.microsoft.com/zh-cn/library/ka0yazs1.aspx

楼主的是冒牌双缓冲
lxf67833508 2010-06-18
  • 打赏
  • 举报
回复
学习下。。。。
kolosi 2010-06-18
  • 打赏
  • 举报
回复
想不changesize不闪烁,要么你让盛放你这个空间的面板doublebuffer了,要么你就不要再onsizechange是重绘,onsizechange是只重绘个方框,onmouseup时再重绘空间。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧