how to stop flickering C# winforms
Finally solved the flickering. Since I was drawing on a panel instead of the form the line of code below will not solve the flickering:
this.SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,
true);
SetStyle must be of type 'YourProject.YourProject' (or derived from it) hence, you have to create a class as such (so that you can use MyPanel which will be derived from SPaint.SPaint and hence allowing you to use doublebuffering directly for the panel - rather than the form):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SPaint;
namespace YourProject
{
public class MyPanel : System.Windows.Forms.Panel
{
public MyPanel()
{
this.SetStyle(
System.Windows.Forms.ControlStyles.UserPaint |
System.Windows.Forms.ControlStyles.AllPaintingInWmPaint |
System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer,
true);
}
}
}
After you've done this(although you should really never edit the designer code unless you truly know what you're doing) you'll have to edit the Form.Designer.cs. Inside this file you will find code that looks like this:
this.panelArea = new YourProject.MyPanel();
The above line needs to be changed to:
this.panelArea = new MyPanel();
After I completed these steps, my paint program no longer flickers.
For anyone else having the same issue, the problem is finally solved.
Enjoy!
How to make my panel stop flickering
Adding this.DoubleDuffered = true;
to the Form
does only affect the Form
, not the Panel
.
So use a doubleBuffered Panel
subclass:
class DrawPanel : Panel
{
public DrawPanel ()
{
this.DoubleBuffered = true;
}
}
However moving large things around will take its toll.
Btw, the PictureBox
class is already doubleBuffered. Also it seems more logical to add the Panel to the PictureBox, not the Form: pictureBox1.Controls.Add(pan);
And adding a pictureBox1.Refresh();
to the MouseMove
.
Update: As you don't draw on the Panel and also need to it to overlap the PictureBox the above ideas do not really apply; using the subclass is not necessary, although it may come handy at some point. And yes, the Panel needs to be added to the Form's Controls collection!
This code works just fine here:
public Form1()
{
InitializeComponent();
// your other init code here
Controls.Add(pan); // add only once
pan.BringToFront();
pan.Hide(); // and hide or show
this.DoubleDuffered = true // !!
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
pan.Hide(); // hide or show
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
pan.Location = pictureBox1.PointToClient(Cursor.Position);
pictureBox1.Refresh(); // !!
Refresh(); // !!
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
pan.Height = 200;
pan.Width = 100;
pan.BackColor = Color.Blue;
pan.Location = pictureBox1.PointToClient(Cursor.Position);
pan.Show(); // and hide or show
}
Looks like you were missing the right combination of doublebuffering the Form
and refreshing both, the Form
and the PictureBox
.
How to prevent flickering in WinForms when quickly updating a value?
Do you have Double Buffering set. If not start there and then other methods as needed.
Avoid Flickering in Windows Forms?
Yet another solution:
//TODO: Don't forget to include using System.Runtime.InteropServices.
internal static class NativeWinAPI
{
internal static readonly int GWL_EXSTYLE = -20;
internal static readonly int WS_EX_COMPOSITED = 0x02000000;
[DllImport("user32")]
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32")]
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
}
And your form constructor should look as follows:
public MyForm()
{
InitializeComponent();
int style = NativeWinAPI.GetWindowLong(this.Handle, NativeWinAPI.GWL_EXSTYLE);
style |= NativeWinAPI.WS_EX_COMPOSITED;
NativeWinAPI.SetWindowLong(this.Handle, NativeWinAPI.GWL_EXSTYLE, style);
}
In the code above, you might change this.Handle
to something like MyFlickeringPanel.Handle
You can read a bit more about it here: Extended Window Styles and here: CreateWindowEx.
With WS_EX_COMPOSITED set, all descendants of a window get
bottom-to-top painting order using double-buffering. Bottom-to-top
painting order allows a descendent window to have translucency (alpha)
and transparency (color-key) effects, but only if the descendent
window also has the WS_EX_TRANSPARENT bit set. Double-buffering allows
the window and its descendents to be painted without flicker.
How to stop flickering when redrawing ellipses in windows forms
As stated out in the comments, you should always use the Graphics
object from the Paint
-event. To invoke a redraw, call Invalidate()
on your control. Do not use Refresh()
(not that bad) or Application.DoEvents()
(very bad) to perform redraws.
Bonus: Pro-Tip for a very smooth drawing experience
Get rid of OnPaintBackground()
, see my other answer here.
With this, you'll get good rendering performance (for GDI+), I use this a lot. You can see it over here in a fun project I made to analyse WinForms control hierarchies: WinFormsCT on GitHub.
Eliminate Flickering in C# WinForms Application
I achieved zero flickering by using sendToBack
and bringToFront
property of the form. I initially loaded both my forms in InitializeForm() function and then simply set these properties on my form on Touch event. By doing so the time to load a form i.e. using .show()
and .hide()
is eliminated.
Note: Both my forms are static
and thus I can apply these properties. In a scenario where which form is to be loaded is decided dynamically, I am not sure whether this will give the desired result. Any better solutions are welcomed.
Related Topics
Inheritance with Base Class Constructor with Parameters
Identityserver4 Role Based Authorization for Web API with ASP.NET Core Identity
JSON.Net - Serialize Property Name Without Quotes
Returning Http Status Code from Web API Controller
Get File Name from Uri String in C#
Detecting Network Connection Speed and Bandwidth Usage in C#
How to Programmatic Disable C# Console Application's Quick Edit Mode
How to Check If a List Is Ordered
How to Implement a Progress Bar in C#
Inconsistency in Divide-By-Zero Behavior Between Different Value Types
What Is the Static Variable Initialization Order Across Classes in C#
Why Does C# (4.0) Not Allow Co- and Contravariance in Generic Class Types
Example Using Hyperlink in Wpf
How to Show File Copy Progress Using Fileinfo.Copyto() in .Net