Как установить защищенное свойство DoubleBuffered
элементов управления в форме, которая страдает от мерцания?
Как дублировать элементы управления .NET в форме?
Ответ 1
Вот более общая версия Dummy solution.
Мы можем использовать отражение для получения защищенного свойства DoubleBuffered, а затем его можно установить как true.
Примечание. Вы должны платить налоги с вашего разработчика, а не использует двойную буферизацию, если пользователь работает в сеансе служб терминалов (например, Remote Desktop). Этот вспомогательный метод не будет включать двойную буферизацию, если человек работает на удаленном рабочем столе.
public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
//Taxes: Remote Desktop Connection and painting
//http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
return;
System.Reflection.PropertyInfo aProp =
typeof(System.Windows.Forms.Control).GetProperty(
"DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(c, true, null);
}
Ответ 2
Отметьте этот поток
Повторяя ядро этого ответа, вы можете включить флаг стиля WS_EX_COMPOSITED в окне, чтобы получить как форму, так и все ее элементы управления с двойным буферизацией. Флаг стиля доступен с XP. Это не делает живопись быстрее, но все окно рисуется в буфер вне экрана и разлетается на экране одним ударом. Заставляя его выглядеть мгновенно глазами пользователя без видимых артефактов. Это не совсем безотказно, некоторые визуальные визуализаторы стилей могут сработать на нем, особенно TabControl, когда у него слишком много вкладок. YMMV.
Вставьте этот код в свой класс формы:
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Большая разница между этим методом и поддержкой двойной буферизации Winform заключается в том, что версия Winform работает только на одном элементе управления в момент времени. Вы по-прежнему будете видеть каждую отдельную контрольную краску. Который может выглядеть как эффект мерцания, особенно если неокрашенный прямоугольник управления плохо контрастирует с фоном окна.
Ответ 3
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);
Ian содержит дополнительную информацию об использовании этого на терминальном сервере.
Ответ 4
public void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
}
Ответ 5
Один из способов - расширить конкретный элемент управления, который вы хотите удвоить буфер, и установить свойство DoubleBuffered внутри элемента управления ctor.
Например:
class Foo : Panel
{
public Foo() { DoubleBuffered = true; }
}
Ответ 6
nobugz получает кредит за метод в своей ссылке, я просто переписываю. Добавьте это переопределение в форму:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
Это работало лучше всего для меня, в Windows 7 я получал большие черные блоки, появляющиеся при изменении размера элемента управления. Теперь контроль теперь отскакивает! Но это лучше.
Ответ 7
Прежде чем пытаться выполнить двойную буферизацию, проверьте, разрешает ли SuspendLayout()/ResumeLayout() вашу проблему.
Ответ 8
Метод расширения, чтобы включить или отключить двойную буферизацию для элементов управления.
public static class ControlExtentions
{
/// <summary>
/// Turn on or off control double buffering (Dirty hack!)
/// </summary>
/// <param name="control">Control to operate</param>
/// <param name="setting">true to turn on double buffering</param>
public static void MakeDoubleBuffered(this Control control, bool setting)
{
Type controlType = control.GetType();
PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(control, setting, null);
}
}
Использование (например, как сделать DataGridView DoubleBuffered):
DataGridView _grid = new DataGridView();
// ...
_grid.MakeDoubleBuffered(true);
Ответ 9
Это вызвало у меня много горя в течение двух дней с помощью стороннего управления, пока я не отследил его.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
Недавно у меня было много отверстий (droppings) при повторной калибровке/перерисовке элемента управления, содержащего несколько других элементов управления.
Я попробовал WS_EX_COMPOSITED и WM_SETREDRAW, но ничего не работал, пока не использовал это:
private void myPanel_SizeChanged(object sender, EventArgs e)
{
Application.DoEvents();
}
Просто хотел передать его.
Ответ 10
Вы также можете наследовать элементы управления в свои собственные классы и установить там свойство. Этот метод также хорош, если вы, как правило, выполняете множество настроек, что одинаково для всех элементов управления.
Ответ 11
версия этого прекрасного решения vb.net....:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
Return cp
End Get
End Property
Ответ 12
Я обнаружил, что простая установка параметра DoubleBuffered в форме автоматически устанавливает все свойства, перечисленные здесь.