无效/更新/刷新不需要 [英] Invalidate / Update / Refresh don't as needed

查看:132
本文介绍了无效/更新/刷新不需要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

在阅读文章并且一周内尝试许多操作均未成功后,我向您寻求帮助和/或见解.我在VS 3.5上使用c#2008.

第一个问题

我有一个表单(绑定到数据表),其中包含几个ComboBox和其他控件(从基本表单继承).组合框包含在面板中(继承所必需).重新填充ComboBox时,首先设置数据源,displaymember等,然后调用绑定源的ResumeBinding().必须按此顺序进行,否则将无法正常工作.添加数据源后,组合框将显示DateSource的第一项.恢复绑定后,将切换到导航器(在BindingSource中选择项目)所选择的项目.用户都可以看到这两种状态.理想情况下,只有最后的最终状态应该可见.

第二个问题
编辑某些条目并单击保存按钮后,会弹出一个消息框,询问用户是否要编辑另一个条目.如果他选择是,该表格将被重置.同样,重置期间的所有中间状态都是可见的.在重新设置完成之前,应该暂停绘画.

方法
* ComboBox.BeginUpdate()... ... .... EndUpdate()
不会改变任何东西. ComboBox继续显示中间状态(恢复绑定之前的第一项).我不知道为什么在我的案例中,BeginUpdate()根本无法如MS文档所宣传的那样起作用:
BeginUpdate方法,以防止每次将项目添加到列表时控件重新绘制ComboBox.
嗯,嗯,不,不是.还是仅在添加项目时阻止重新粉刷,而在选择其他项目时不阻止粉刷?任何见解都受到高度赞赏,我真的很想知道为什么这种方法在这里不起作用.

* this.SuspendLayout()-> this.ResumeLayout()
在表单和面板上进行了尝试,没有任何效果-完全没有效果.

* ceztko使用WM_SETREDRAW win32消息的方法
http://stackoverflow.com/questions/487661/我如何将绘画暂停用于控制及其子对象
我使用了最后一个解决方案(以下是ng5000的相同解决方案,但未使用P/Invoke),但也尝试了最受接受的解决方案.

这实际上适用于问题1,组合框不再显示中间状态.但是,如果我在恢复绑定之前使用Resume()方法,它们只会显示最终状态.

该问题在问题2中变得更加明显:中间状态被压制,但是窗体不能正确地重新绘制(除非我最小化和最大化它或类似的东西):弹出消息保持可见,控件在使用挂起方法.

Invalidate()和Update()根本不执行任何操作.我在表单,面板和控件上进行了尝试.

Refresh()触发重新绘制,但是所有中间状态也都返回了.

这一点我一点都不明白.据我了解,Invalidate()-> Update()应该等于Refresh().显然不是. Refresh()的作用更多.刷新甚至会使以前暂停的所有中间状态重新出现.那怎么可能?

我完全感到困惑,没有任何可行的解决方案.任何帮助是极大的赞赏.如果没有解决方案,那很好,我可以付诸实践.但是至少我想了解为什么这些东西不起作用(应有的原因).

非常感谢您,长文本致谢
Pesche

Hi board,

after reading articles and unsuccessfully trying many things for a week, I turn to you for some help and/or insight. I am using c# 2008 with VS 3.5.

First Problem

I have a form (bound to a datatable) with a couple of ComboBoxes and other controls (inherited from a base form). The ComboBoxes are contained within a panel (required for inheritance). When I repopulate the ComboBoxes, I first set the data source, displaymember etc, then I call ResumeBinding() of the binding source. It has to be done in this order, otherwise it would not work. After adding the DataSource, the ComboBoxes will show the first item of the DateSource. After resuming binding, the will switch to the item as chosen by the navigator (which selects items in the BindingSource). Both states are visible to the user. Ideally, only the last, final state should be visible.

Second Problem
After editing some entry and hitting the save button, a message box pops up to ask the user if he wants to edit another entry. If he chooses yes, the form will be reset. Again, all the intermediate states during resetting are visible. The painting should be suspended until the resetting is complete.

Approaches
* ComboBox.BeginUpdate() ... do stuff ... .EndUpdate()
Doesn''t change anything. The ComboBoxes keep showing the intermediate states (first item, before binding is resumed). I have no idea why BeginUpdate() in my case does not work at all as advertised by the MS documentation:
BeginUpdate method to prevent the control from repainting the ComboBox each time an item is added to the list.
Hm, well, no, it doesn''t. Or does it exclusively prevent repainting when items are added, but not when other items are selected? Any insights are highly appreciated, I would really like to understand why this method doesn''t work here.

* this.SuspendLayout() -> this.ResumeLayout()
Tried it on the form and the panel, nothing worked - no effect at all.

* Method by ceztko using the WM_SETREDRAW win32 message
http://stackoverflow.com/questions/487661/how-do-i-suspend-painting-for-a-control-and-its-children
I used the last solution (The following is the same solution of ng5000 but doesn''t use P/Invoke), but also tried the most accepted one.

This actually works for problem 1, the comboboxes no longer show the intermediate state. Yet, they only show the final state, if I use the Resume() method before resuming binding.

That issue becomes more apparent with problem 2: The intermediate states are repressed, but the form does not repaint properly (unless I minimize and maximize it or stuff like that): the popup message remains visible, the controls show the last value before using the Suspend method.

Invalidate() and Update() do nothing at all. I tried them on the form, the panel and the controls.

Refresh() triggers a repaint, but then, all the intermediate states are back, too.

This, I don''t understand at all. To my understanding, Invalidate() -> Update() should be equal to Refresh(). Apparently, it''s not. Refresh() does more. Refresh even makes all the intermediate states reappear that were suspended before. How is that possible?

I am totally confused and left without any working solution. Any help is greatly appreciated. If there is no solution, fine, I got to life with that. But at least I would like to understand why these things do not work (as they should).

Thank you very much and sorry for the long text
Pesche

推荐答案

最后,我可以为上述问题弄清楚一些解释和部分解决方案:

*据我了解,Invalidate()-> Update()应该等于Refresh().显然不是. Refresh()做得更多.

错误,Refresh()等于Invalidate( true )-> Update()
此布尔值的MS描述:
Invalidate(Boolean)使控件的特定区域无效,并导致将 paint消息发送到控件. (可选)使分配给该控件的子控件无效.

我在一些简单的ComboBoxes上对此进行了测试:当您不传递此参数或将其传递为false时,ComboBox不会在ResumeDrawing上重绘,仅当您切换到下一个项目(或执行其他一些操作会发送绘画消息).
当您传递true时,它将在ResumeDrawing时立即重绘.
因此,我不知道它如何影响子控件,但对我来说,重要的部分似乎是发送绘画消息(如果您传递假,则不会).

我意识到的另一件事:当您使用ceztko方法暂停绘画ComboBox时,它很完美,直到您删除了ComboBox的DataSource.这会以某种方式恢复绘画.删除数据源时,使控件无效似乎是合乎逻辑的.显然,它还会发送WM_SETREDRAW消息,从而撤消SuspendDrawing方法.唯一有帮助的是在ComboBoxes的容器上使用SuspendDrawing而不是ComboBoxes本身.

在以下情况下避免问题的另一招:
1)用户按下SaveBtn
2)弹出MessageBox询问用户是否应重置(或关闭)表单
3)用户选择重置表格
4)SuspendDrawing被称为
->这会导致MessageBox的可见可见的分解过程,因为在重新绘制表单之前已暂停了绘图(-> MessageBox的图形状态仍然存在).
->为避免这种情况,只需在用户单击MessageBox中的答案后(评估对话框结果时),立即在窗体上调用Refresh().这样,您可以在调用SuspendDrawing之前强制窗体重新绘制并摆脱MessageBox.
Finally, I could figure out some explanations and partial solutions to the above problems:

*To my understanding, Invalidate() -> Update() should be equal to Refresh(). Apparently, it''s not. Refresh() does more.

Wrong, Refresh() equals Invalidate(true) -> Update()
MS description of this boolean:
Invalidate(Boolean) Invalidates a specific region of the control and causes a paint message to be sent to the control. Optionally, invalidates the child controls assigned to the control.

I tested this on some simple ComboBoxes: When you don''t pass this parameter or pass it as false, the ComboBox won''t redraw upon ResumeDrawing, only when you switch to the next item (or do something else that would send a paint message).
When you pass true, it will redraw immediately upon ResumeDrawing.
So I don''t know how it affects the child controls, but to me, the important part seems to be sending the paint message (which it won''t if you pass false).

Another thing I realized: When you suspend painting of a ComboBox using the ceztko method, it works perfect until you remove the DataSource of the ComboBox. This somehow resumes painting. It seems logical, that the Control is invalidated when you remove the DataSource. Apparently, it also send a WM_SETREDRAW message, thus undoing the SuspendDrawing method. The only thing that helped here was to use SuspendDrawing on the container of the ComboBoxes instead of the ComboBoxes themselves.

Yet another trick to avoid problems in the following scenario:
1) User presses SaveBtn
2) MessageBox pops up to ask user, if the form should be reset (or closed)
3) User chooses to reset the form
4) SuspendDrawing is called
--> this can result in a nasty visible disintegration process of the MessageBox, because drawing is suspended before the form has been redrawn (-> the graphical presence of the MessageBox is still there).
-> To avoid this just call Refresh() on the form, immediately after the user clicks on an answer in the MessageBox (when evaluating the dialog result). That way, you force the form to redraw and get rid of the MessageBox, before SuspendDrawing is called.


这篇关于无效/更新/刷新不需要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆