我想这是一般性问题,并不仅限于ComboBox,但我对ComboBox有特殊的问题。我用MyCB扩展了ComboBox对象MyCB : ComboBox
)
每当我将鼠标悬停在控件上,离开控件,展开选择框或选择一个值时,控件就会闪烁。有一段时间我可以看到默认(未替换)控件,它会立即被我的替换。
我相信正在发生的事情是Windows首先绘制“原始”控件(通过调用base.WndProc()
),然后重新绘制它。
问题是,我可以以某种方式阻止窗户绘制它自己的控制并立即绘制我的吗?
以下是覆盖WndProc
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_PAINT)
{
Graphics gg = this.CreateGraphics();
gg.FillRectangle(BorderBrush, this.ClientRectangle);
// ... //
//Draw the arrow
gg.FillPath(ArrowBrush, pth);
// ... //
if(this.Text == "")
gg.DrawString("-- SELECT --", this.Font, new SolidBrush(Color.Black), rf, sf);
else
gg.DrawString(this.Text, this.Font, new SolidBrush(Color.Black), rf, sf);
gg.Dispose();
}
}
到目前为止我尝试了什么:
我知道我不能这样做:
if (m.Msg == WM_PAINT)
{
...
}
else
{
base.WndProc(ref m);
}
因为这将导致控制无限地重绘自己(不确定原因)
我能够通过添加此代码来消除鼠标离开/进入控件时发生的闪烁
if (m.Msg == WM_MOUSEFIRST || m.Msg == WM_MOUSELEAVE) // 0x0200 0x02A3
{
m.Result = (IntPtr)1;
}
else
{
base.WndProc(ref m);
if (m.Msg == WM_PAINT)
{
...
}
}
然而,这并没有完全解决问题
答案 0 :(得分:0)
public CustomComboBox()
{
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == Win32.WM_MOUSEFIRST || m.Msg == Win32.WM_MOUSELEAVE || m.Msg == Win32.WM_MOUSEHOVER) //0x0200, 0x02A3, 0x02A1
{
m.Result = (IntPtr)1;
return;
}
base.WndProc(ref m);
if (m.Msg == Win32.WM_PAINT)
{
IntPtr hDC = Win32.GetWindowDC(m.HWnd);
Graphics g = Graphics.FromHdc(hDC);
g.SmoothingMode = SmoothingMode.HighSpeed;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
if (Text.Length == 0)
{
StringFormat stringFormat = new StringFormat
{
Alignment = StringAlignment.Near,
LineAlignment = StringAlignment.Near
};
g.DrawString("Water Marks", Font, new SolidBrush(Color.FromArgb(51, 51, 51)), (Bounds.Width - 2), FontHeight + 2, stringFormat);
}
Pen border = new Pen(ui_BorderLineColor, 1);
g.DrawRectangle(border, 0, 0, this.Width - 1, this.Height - 1);
g.Dispose();
Win32.ReleaseDC(m.HWnd, hDC);
}
}
protected override void InitLayout()
{
base.InitLayout();
DropDownStyle = ComboBoxStyle.DropDownList; //Works only in DropDownList
}