作者: 乔克斯
查看: 3418|回复: 7

[源码] 【GDI+编程经验】滚动条、缩放、绘制闪烁

[复制链接]
乔克斯 发表于 2014-7-23 01:33:53 | 显示全部楼层 |阅读模式
查看: 3418|回复: 7

  我们在使用GDI+实现类似画图板这样的系统时,经常需要支持平移、滚动条、缩放等功能、解决绘制时的闪烁,对于缺乏GDI+开发经验的朋友,经常会在这些问题上纠缠一段或长或短的时间。在这里,我将自己的经验小结一下,给后来的朋友作个参考。


1.如何解决绘制闪烁?

(1)所有的绘制动作都应该Paint事件中完成。

  比如,即使我们要拖动一个View object,通常在MouseMove事件中处理拖动行为,但是不要在MouseMove事件中调用Graphics.Draw方法,而是应该采用Command模式,将要绘制的动作封装为一个对象,传递到下一次的Paint事件中再绘制。

(2)设置双缓冲。

  通常我们会选择在某个控件的表面进行绘制,那么在初始化时,可以通过执行下面的代码来启用双缓冲:

[C#] 纯文本查看 复制代码
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);

  注意,SetStyle是一个Control基类的一个Protected方法,也就是说,只能在其派生类中才能调用该方法。

  通常,我是定义一个从Control继承的自定义控件,然后在构造方法中进行双缓冲设置,如:

[C#] 纯文本查看 复制代码
public partial class ViewPanel : UserControl
{
    public ViewPanel() {
        InitializeComponent();
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
    }
}

(3)重新绘制发生变化的区域,而不是整个区域全部重绘。

  Control的Invalidate方法有一个重载接收Region类型的参数,表示下次paint时要重绘的区域。比如,当我们拖动一个对象时,只需要重绘比这个对象的Bounds大一点的区域即可。


2.滚动条与缩放

  当需要支持滚动条和缩放时,就需要采用一系列的坐标变换来正确的记录坐标和绘制图像,这些过程是比较繁琐的。幸运的是,GDI+能为我们减轻一部分这方面的负担。当绘制view object时,只要我们指定Graphics对象的几个参数,Graphics对象就会自动采用正确的比例和偏移来绘制所有的view object了。比如:

[C#] 纯文本查看 复制代码
//Graphics g ;
g.PageUnit = GraphicsUnit.Pixel; //GraphicsUnit.Pixel才支持缩放与偏移绘制。
g.TranslateTransform(this.hScrollValue, this.vScrollValue); //设置滚动条的当前位置
g.PageScale = this.Scale; //设置缩放比例

g.Draw(......);


回复 论坛版权

使用道具 举报

esf5021314 发表于 2016-10-21 12:47:08 | 显示全部楼层
居然给我留个沙发,那我就个客气了,谢谢楼猪分享~
王龙 发表于 2017-3-26 20:24:54 | 显示全部楼层
收藏此帖,日后学习
1080xb 发表于 2018-3-29 08:33:41 | 显示全部楼层
滚动条、缩放、绘制闪烁,学习了
bryan 发表于 2018-6-23 22:36:25 | 显示全部楼层
绘图的教学 太重要了,感谢分享了。~~
113793431 发表于 2019-1-4 17:11:47 | 显示全部楼层
感谢分享
回复

使用道具 举报

zzzzzz 发表于 2019-1-11 17:39:40 | 显示全部楼层
没看懂,还是没解决问题啊,楼主
l375527548 发表于 2019-3-14 00:15:56 | 显示全部楼层
学习经验,防闪烁
您需要登录后才可以回帖 登录 | 加入CSkin论坛

本版积分规则

QQ|申请友链|小黑屋|手机版|Archiver|CSkin ( 粤ICP备13070794号

Powered by Discuz! X3.2  © 2001-2013 Comsenz Inc.  Designed by ARTERY.cn
GMT+8, 2019-6-17 11:37, Processed in 1.204743 second(s), 30 queries , Gzip On.

快速回复 返回顶部 返回列表