Избегайте мерцания в Windows Forms?

двойная буферизация не работает со списком. есть ли другие способы избежать мерцания в windows forms?

У меня есть одна форма windows с количеством панелей в ней. Я показываю только одну панель за раз на основе моего выбора меню.

У меня есть одна панель,одна панель заголовка и поле со списком. на основе выбранного элемента этого комбинированного поля заполняются gridview1 и 2. когда я быстро выбираю элемент со списком, используя стрелку клавиатуры вниз, значок панель и панель заголовка всегда перекрашиваются. мне нужно сохранить и то и другое без изменений. это две панели, производящие некоторый мигающий эффект (т. е. они мигают или мигают), когда я меняю индекс выбранного поля со списком. есть ли способ избежать этого мигания.? я попробовал включить двойной буфер в конструкторе формы и событии загрузки формы. пожалуйста помочь..............

InitializeComponent();
                this.SetStyle(ControlStyles.DoubleBuffer, true);
                this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
                this.SetStyle(ControlStyles.UserPaint, true);
                this.SetStyle(ControlStyles.SupportsTransparentBackColor, false);
                this.SetStyle(ControlStyles.Opaque, false);
                this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
                this.SetStyle(ControlStyles.ResizeRedraw, true);

Я пробовал этот код в form constuctor и form load event

3 ответов


еще одно решение:

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

и ваш конструктор формы должен выглядеть следующим образом:

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

в коде выше вы можете изменить this.Handle что-то вроде MyFlickeringPanel.Handle

вы можете прочитать немного больше об этом здесь: Расширенные Стили Окна и здесь: CreateWindowEx.

С набором WS_EX_COMPOSITED все потомки окна получают снизу вверх порядок рисования с использованием двойной буферизации. Снизу вверх порядок рисования позволяет нисходящему окну иметь полупрозрачность (Альфа) и Эффекты прозрачности (color-key), но только если потомок в окне также установлен бит WS_EX_TRANSPARENT. Двойная буферизация позволяет окно и его потомки должны быть расписаны без единого проблеска.


Решение #1:
Использовать ComboxBox.BeginUpdate() перед добавлением элементов. Это предотвратит Control от перекрашивания ComboBox каждый раз, когда элемент добавляется в список. После добавления элементов, вы можете использовать ComboBox.EndUpdate() перекрашивать.

решение № 2

private void EnableDoubleBuffering()
{
    this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
}

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams handleParam = base.CreateParams;
            handleParam.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED       
            return handleParam;
        }
    }