1. Double Buffering is used for forms and controls to reduce image flickering (double buffering is used when an image is drawn)
For most applications, the default double buffer provided by. NET Framework will provide the best effect. By default, standard Windows Forms controls are dual-buffered. You can enable the default double buffer for the form and the created control in two ways. Either way is to set the doublebuffered attribute to true, or call the setstyle method to set the optimizeddoublebuffer flag to true. Both methods enable the default double buffer for the form or control and provide non-blinking graphics. We recommend that you call the setstyle method only for the custom control that has compiled all the rendered code for it.
Add the following code to the constructor:
This. doublebuffered = true; // you can specify this form.
Setstyle (controlstyles. userpaint, true );
Setstyle (controlstyles. allpaintinginwmpaint, true); // The background cannot be erased.
Setstyle (controlstyles. doublebuffer, true); // Double Buffer
// Setstyle (controlstyles. doublebuffer | controlstyles. optimizeddoublebuffer | controlstyles. allpaintinginwmpaint, true );
// Updatestyles ();
Ii. Summary of solutions to the flickering problem of C # controls
The Code has been optimized recently. After the test, the results are still good, but the interface will flash. Specifically, the Treeview control will flash, the language is C #, And the IDE is vs2005. After reading some materials and using some basic technologies (such as enabling dual-buffering), I found that the performance was ineffective.
Therefore, the profiler tool is used to find out the bottleneck in the endupdate operation of the interface after each update (this is used to reduce the number of page updates, but this is not ideal because there are many elements in the control ), I guess every update ,. net underlying layer will update and repaint each element, so the speed will be slow, resulting in flickering. However, the use of double buffering should have better results. Looking at the code again, we may find that the update operation is too frequent, which reduces the speed and improves, but still does not work.
Continue online, and finally find a suitable solution. It turns out that the canvas is cleared and re-drawn at the underlying layer each time. This is the main cause of flickering. Therefore, the message sending function operation is reloaded to disable this message. The Code is as follows:
Protected override void wndproc (ref message m)
{
If (M. MSG = 0x0014) // disable background message clearing
Return;
Base. wndproc (ref m );
}
Successful!
Note: Dual-buffering is useful when updates are not frequent and the number of elements in the control is not very large. Once there are too many elements, each update takes a long time. Even if dual buffering is used, the problem still cannot be solved. In my opinion, the ideal method is to disable background message clearing.
Appendix: record of failed attempts
1) Use setstyle
On the Internet, you can use the setstyle function to set the parameters of the control, specifically:
Setstyle (controlstyles. userpaint | controlstyles. allpaintinginwmpaint | controlstyles. optimizeddoublebuffer, true );
These three option parameters depend on the former and must coexist; otherwise, they are invalid. This function itself is protected, so you must inherit a control before using it.
This goal is consistent with the preceding solution. It also prevents background clearing and dual buffering. However, you need to use the user rendering option, which is all for user plotting. This requires you to plot all controls by yourself, which is troublesome. Therefore, this method is not completely unavailable, but requires additional work and is not recommended. I am not using it either.
2) use beginupdate and endupdate
These operations have a good effect on scenarios where you need to update controls in batches. For example, a large number of nodes are added in batch during initialization. The disadvantage is that it cannot be updated immediately. Therefore, it is not applicable to scenarios where frequent node updates and immediate display of the interface are required. If you use it and do not disable clearing the interface message, the control will appear to flash continuously, and the content is mostly white-based and almost invisible (depending on the complexity of the video ). Because all interface updates are completed at endupdate, too many operations lead to a long blocking time for endupdate and are cleared first. After the update, the interface looks blank for a long time.
3) Use controlstyles. enablenotifymessage Option
The role of this option is the same as that of the correct solution. The usage is as follows:
Setstyle (controlstyles. enablenotifymessage, true );
Protected override void onnotifymessage (message m)
{
// Write the message filtering code here
}
However, the actual experiment shows no effect. I don't know why, so I didn't go into details.
3. In a winfrom test, the timer control can be used to regularly refresh the control to be refreshed.
Iv. Local refresh of C # winform
During the winform interface program, the background processing often takes a lot of time, which causes the interface to be suspended. There are two ways to solve the problem of false interface: either put the processing method that takes a lot of time into other threads, or put the interface display into other threads. The first method should be relatively simple. Open a separate thread to process data and display the processed data to the interface. However, we often need to calculate some content in the main program, otherwise the changes may be relatively large. Therefore, let's talk about the second method.
Multithreading is also used, but there is a little problem with the refreshing of C # In other threads, that is, the interface cannot be operated across threads. This can be solved using the invoke method of the control:
Private delegate void crossthread ();
Control control = ....;
Crossthread cross = delegate ()
{
Control. Refresh ();
};
Control. Invoke (Cross );
This allows the control to refresh the interface in other threads.
In addition, the general method after the new thread is opened:
Private void invaliatecontrol (Control)
{
Thread t = new thread (
New threadstart (delegate ()
{
Crossthread cross = delegate ()
{
Control. Refresh ();
};
Control. Invoke (Cross );
}
));
}
In this way, you can call this method to refresh the control at any time without refreshing the entire interface. If the same control is refreshed multiple times in a row, you can add a member variable as a tag to avoid the same control from refreshing multiple times in a row, improving some performance.
Supplement: This method may cause problems when the main thread calls time-consuming operations. After verification, the invoke function is called, and the interface is refreshed on the main thread.