Skip to content

Instantly share code, notes, and snippets.

@Roman-Port
Created August 8, 2022 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Roman-Port/1311d51976cc14da02804a656ca4ebef to your computer and use it in GitHub Desktop.
Save Roman-Port/1311d51976cc14da02804a656ca4ebef to your computer and use it in GitHub Desktop.
Finally, double-buffered, non-flickering WinForms TreeView in Windows 10
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
namespace DddProperyEditorGUI.Util
{
/*
* Mostly based off of https://sites.google.com/a/nomad-net.info/dev/articles/double-buffered-tree-and-list-views
* Updated to work with Windows 10 by RomanPort
*/
class BufferedTreeView : TreeView
{
private const int TV_FIRST = 0x1100;
private const int TVM_SETBKCOLOR = TV_FIRST + 29;
private const int TVM_SETEXTENDEDSTYLE = TV_FIRST + 44;
private const int TVS_EX_DOUBLEBUFFER = 0x0004;
private const int WM_PRINTCLIENT = 0x0318;
private const int PRF_CLIENT = 0x00000004;
public BufferedTreeView()
{
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
//Send message to set the styles
SendMessage(Handle, TVM_SETEXTENDEDSTYLE, (IntPtr)TVS_EX_DOUBLEBUFFER, (IntPtr)TVS_EX_DOUBLEBUFFER);
//Enable our override for OnPaint - https://stackoverflow.com/questions/2215393/onpaint-override-is-never-called
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
//Not sure why this is needed, but without it you get weird black boxes
SendMessage(Handle, TVM_SETBKCOLOR, IntPtr.Zero, (IntPtr)ColorTranslator.ToWin32(BackColor));
}
protected override void OnPaint(PaintEventArgs e)
{
if (GetStyle(ControlStyles.UserPaint))
{
Message m = new Message();
m.HWnd = Handle;
m.Msg = WM_PRINTCLIENT;
m.WParam = e.Graphics.GetHdc();
m.LParam = (IntPtr)PRF_CLIENT;
DefWndProc(ref m);
e.Graphics.ReleaseHdc(m.WParam);
}
base.OnPaint(e);
}
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment