WEB开发网
开发学院软件开发C语言 如何避免多控件窗体重新布局时闪烁 阅读

如何避免多控件窗体重新布局时闪烁

 2010-09-30 21:00:08 来源:WEB开发网   
核心提示:适用场景: 需要在某容器控件中动态装载多个子控件,而且该容器控件可能需要改变WindowFormState,即从Normal转变为Maxmized,或者是其他状态转换啦, what ever :)如果没有应用任何特殊处理,你就会发现,当容器控件状态转换时,其上的子控件在经过一阵狂闪之后(可能背景控件颜色和自身相互交替出

适用场景:

需要在某容器控件中动态装载多个子控件,而且该容器控件可能需要改变WindowFormState,即从Normal转变为Maxmized,或者是其他状态转换啦, what ever :)

如果没有应用任何特殊处理,你就会发现,当容器控件状态转换时,其上的子控件在经过一阵狂闪之后(可能背景控件颜色和自身相互交替出现),最终恢复至平静; 这种情形当然无论是程序员自己和客户都不愿意看到的

ok,废话一通之后,咱们开始解释原因,以及考虑解决方案

为什么会闪烁?

因为窗体控件状态转换时,windows需要负责"擦除"其背景,重新绘制,在一台性能并不优良的终端上(很大可能程度上客户端电脑都不是那么强劲吧) ,这个过程不是一时半会就能完成的,尤其对于很多个子控件的情况,因此就…

解决之道?

如果稍微写过WinForm程序的同学,肯定或多或少的用过ListView控件,简单易用嘛 :) 那么一定也知道该控件有2个比较有意思的方法:

BeginUpdate

Prevents the control from drawing until the EndUpdate method is called.

EndUpdate

Resumes drawing of the list view control after drawing is suspended by the BeginUpdate method.

从msdn的解释来看,这2个方法的应用能解决往ListView控件中分多次Add ListViewItem时闪烁的问题,ok,既然它能这么处理,咱们自己的容器控件为什么不能依葫芦画瓢呢?

btw. 其实我一开始也没任何好方法解决闪烁问题,后来偶尔想到ListView的此特性 :)

看看ListView.BeginUpdateInternal方法怎么写:

internal void BeginUpdateInternal()
{
    if (this.IsHandleCreated)
    {
        if (this.updateCount == 0)
        {
            this.SendMessage(11, 0, 0);
        }
        this.updateCount = (short) (this.updateCount + 1);
    }
}

1 2  下一页

Tags:如何 避免 控件

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接