UI开发时, UI消息处理过程混乱的解决方法

来源:互联网 发布:ip网络加速器免费版 编辑:程序博客网 时间:2024/05/29 04:49

     最近修了一个Bug, 发现在.net 框架下, 消息处理的函数混乱, 导致一些不可预知的错误产生,比如当一个Datagrid view 的cell还在编辑的过程中的时候, 其他的消息处理函数对这个cell 进行了重新写内容的操作,会造成程序的Crash. The exception is "Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function." 如何解决这个问题呢, 给出了我的看法。

    下面首先对这个问题进行描述。

    有两个List Control, 分别为A和B, 还有一个datagridview C, 他们之间的响应关系如下:

    1)当选中A的一个item时, 会更新B和C的内容, 并使选B和C选中的内容为Highlight状态

    2)当选中B或C的一个item时, 会更新其他两个的选中状态并更新内容。

    3)当从C中更新数据时, A中相应的内容也会更改。并能够根据C中当前的选中状态更新A中的选中状态。

本来这个问题并不复杂, 但是响应消息偏偏都用了SelectionChange来处理消息, 这个问题就复杂多了。我们假设这三个消息处理函数为Afunc(), Bfunc(), Cfunc().   看下面的例子:

     当A更改选中的状态的时候, 消息是怎么走的呢?

     1)响应Afunc(), 在Afunc中找到响应的B的对应的数据,并使其选中的状态改变。

     2)由于B的选中状态已经改变, Windows响应了Bfunc(), 此时程序已经进入Bfunc()来处理,注意此时第一次进入Afunc()还没有走完。

      3)进入Bfunc(), 在Bfunc()中,根据当前的状态更改A的选中状态, 这是Windows响应了Afunc(), 这时Bfunc()还没有走完

      4)进入Afunc(), 更改B的选中状态, 由于现在B的选中状态和前面相同, 所以不会再次触发Bfunc().

      5)   Afunc()走完, 返回Bfunc().

      6)  Bfunc()走完,返回到Afunc().

      7) Afunc()走完, 返回到Afunc().

复杂不? 也不知道一开始是谁写的,不会用这个久别用这个消息处理函数阿。真郁闷!!!!

     解决方法:

     1)把所有selectionChange的消息的响应,全部改为对click消息的响应,这样就可以彻底把对用户的消息响应和程序中消息更改彻底分开了。这样就不会产生如上的ugly 的处理过程了。

    2)没有更好的了。就用上面的吧

总结:在处理控件的消息过程中,一定要注意对消息响应类型的选择,否则会造成灾难性的后果。把用户输入的消息和程序中对控件的消息彻底分开,这样才能保证消息处理函数的原子性,不会产生其他不可控的结果。

    

    


原创粉丝点击