Click here to Skip to main content
15,890,932 members
Please Sign up or sign in to vote.
4.86/5 (4 votes)
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
Posted
Updated 11-Aug-11 8:15am
v2

1 solution

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.
 
Share this answer
 
Comments
BillWoodruff 15-Aug-11 2:01am    
+5 for your obvious initiative, and efforts to solve your problem ! Also, you might take a look at the various 'SetStyle parameters you can use in a WinForms app. And I assume you've already examined such WinForm parameters as 'DoubleBuffered.

good luck, Bill
spitfire_ch 16-Aug-11 17:36pm    
Thank you, Bill! I have already looked into but not yet tried DoubleBuffered. I didn't know about the SetStyle parameters in this context. I'll give them a closer look, thanks for the hint!

Best regards
Pesche

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900