Метод CreateParams. Как правильно пользоваться для устранения мерцания?
Есть класс CustomProgressBar, нужно было кроме прогресса отображать процент заполнения ползунка в текстовом формате, чего не делает стандартный ProgressBar:
class CustomProgressBar : ProgressBar
{
public String CustomText { get; set; }
public CustomProgressBar()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
Rectangle rect = ClientRectangle;
Graphics g = e.Graphics;
ProgressBarRenderer.DrawHorizontalBar(g, rect);
rect.Inflate(-3, -3);
if (Value > 0)
{
Rectangle clip = new Rectangle(rect.X, rect.Y, (int)(((float)Value / (float)Maximum) * (float)rect.Width),
rect.Height);
ProgressBarRenderer.DrawHorizontalChunks(g, clip);
}
using (Font f = new Font(FontFamily.GenericSerif, 10))
{
SizeF len = g.MeasureString(CustomText, f);
Point location = new Point(Convert.ToInt32((Width / 2) - len.Width / 2),
Convert.ToInt32((Height / 2) - len.Height / 2));
g.DrawString(CustomText, f, Brushes.Black, location);
}
}
//Для устранения мерцания контрола применяем двойную буферизацию на уровне формы, а не на уровне контрола
protected override CreateParams CreateParams
{
get
{
CreateParams myParams = base.CreateParams;
// Установка флага для двойной буферизации WS_EX_COMPOSITED
myParams.ExStyle |= 0x02000000;
return myParams;
}
}
}
} В классе есть переопределенный метод protected override CreateParams CreateParams. Там, откуда я его взял, он был прописан в определении пользовательского контрола. https://www.codeproject.com/Articles/1082902/How-to-Paint-on-Top-of-a-ProgressBar-using-Csharp (2016 год) Пишут что в отличие от свойства DoubleBuffered, этот метод устраняет мерцание для всей формы и контролов на ней, но вот вставляют ее кто куда, то в код основной формы, то в код пользовательского контрола (как здесь)... Так где же все-таки правильно переопределять CreateParams?Будет ли она так же работать, если переопределить в кастомном контроле?
Ответы (1 шт):
Говорить тут о "двойной буферизации на уровне формы" тут, строго говоря, неправильно. Это жаргон, который возник из-за того, что чаще всего двойную буферизацию включают на уровне формы. Вот, что делает WS_EX_COMPOSITED по документации:
Paints all descendants of a window in 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.
Этот стиль включает двойную буферизацию для окна и всех его дочерних окон. Слово окно здесь следует понимать в терминологии Windows - то, что имеет дескриптор окна, то есть любой элемент управления Windows Forms также считается окном. То есть вполне нормально переопределить CreateParams для установки стиля окна и в элементе управления, если это работает в вашем случае. По моим тестам, все работает, и мерцание надписи устраняется.