Как удвоить буфер.ЧИСТЫЕ элементы управления в форме?

StackOverflow https://stackoverflow.com/questions/76993

Вопрос

Как я могу установить защищенный DoubleBuffered свойство элементов управления в форме, которые страдают от мерцания?

Это было полезно?

Решение

Вот более общая версия Решение манекена.

Мы можем использовать отражение, чтобы добраться до защищенного Двойной буфер свойство, и затем оно может быть установлено в верно.

Примечание:Ты должен платите налоги застройщику и не используйте двойную буферизацию, если пользователь работает в сеансе служб терминалов (например,Удаленный рабочий стол) Этот вспомогательный метод не включит двойную буферизацию, если пользователь работает на удаленном рабочем столе.

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); 
}

Другие советы

Проверить этот поток

Повторяя суть этого ответа, вы можете включить флаг стиля WS_EX_COMPOSITED в окне, чтобы получить как форму, так и все ее элементы управления с двойной буферизацией.Флаг стиля доступен начиная с XP.Это не ускоряет рисование, но все окно отрисовывается в закадровом буфере и размазывается по экрану одним ударом.Чтобы он выглядел мгновенно в глазах пользователя без видимых артефактов рисования.Это не совсем безотказно, некоторые средства визуализации визуальных стилей могут давать сбои, особенно TabControl, когда в нем слишком много вкладок.ИММВ.

Вставьте этот код в свой класс form:

protected override CreateParams CreateParams {
    get {
        var cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;    // Turn on WS_EX_COMPOSITED
        return cp;
    } 
}

Большая разница между этим методом и поддержкой двойной буферизации Winform заключается в том, что версия Winform работает только с одним элементом управления одновременно.Вы по-прежнему будете видеть, что каждый отдельный элемент управления рисует сам по себе.Это также может выглядеть как эффект мерцания, особенно если неокрашенный прямоугольник управления сильно контрастирует с фоном окна.

System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
    .GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);

Йен содержит еще некоторую информацию об использовании этого на сервере терминалов.

public void EnableDoubleBuffering()
{
   this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}

Один из способов - расширить конкретный элемент управления, который вы хотите удвоить в буфере, и установить свойство DoubleBuffered внутри ctor элемента управления.

Например:

class Foo : Panel
{
    public Foo() { DoubleBuffered = true; }
}

нобугз получает похвалу за метод по своей ссылке, я просто перепостирую.Добавьте это переопределение в Форму:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

У меня это сработало лучше всего, в Windows 7 у меня появлялись большие черные блоки, когда я изменял размер тяжелой формы элемента управления.Вместо этого элемент управления отскакивает!Но так даже лучше.

Способ расширения чтобы включить или выключить двойную буферизацию для элементов управления

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 с двойной буферизацией):

DataGridView _grid = new DataGridView();
//  ...
_grid.MakeDoubleBuffered(true);

Прежде чем попробовать двойную буферизацию, посмотрите, решат ли вашу проблему SuspendLayout() / ResumeLayout().

Это вызвало у меня лот от горя в течение двух дней управлялся третьей стороной, пока я не выследил его.

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

Недавно у меня было много отверстий (помет) при изменении размера / перерисовке элемента управления, содержащего несколько других элементов управления.

Я пробовал WS_EX_COMPOSITED и WM_SETREDRAW, но ничего не получалось, пока я не использовал это:

private void myPanel_SizeChanged(object sender, EventArgs e)
{
     Application.DoEvents();
}

Просто хотел передать это дальше.

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

Вы также можете наследовать элементы управления в свои собственные классы и задать свойство там.Этот метод также хорош, если вы, как правило, выполняете множество настроек, которые одинаковы для всех элементов управления.

Я обнаружил, что простая установка параметра DoubleBuffered в форме автоматически устанавливает все перечисленные здесь свойства.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top