Я рисую комбо-бокс, и я переопределил OnPaint
и OnDrawItem
. Пока все отлично работает.
Однако после того, как я выбрал элемент из списка и список закрылся, выбранный элемент не отображается в текстовой части поля со списком.
Какие сообщения мне нужно обработать, чтобы нарисовать предмет там?
Я добавил следующее при обработке WM_PAINT:
if (SelectedIndex == -1)
{
g.FillRectangle(brush, this.ClientRectangle);
}
Должен ли я рисовать в WndProc
или OnPaint
?
UPDATE:
Это код для событий WndProc
и OnDrawItem
. В WndProc
я рисую surace элемента управления (текстовая часть, кнопка, рамка). В DrawItem
я рисую предмет.
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_PAINT)
{
var dc = GetWindowDC(this.Handle);
using (var g = Graphics.FromHdc(dc))
{
var theme = ThemeManager.Theme;
if (theme == null)
{
var outer = new Rectangle(0, 0, this.Width, this.Height);
var inner = new Rectangle(1, 1, this.Width - 2, this.Height - 2);
ControlPaint.DrawBorder(g, outer, Color.Black, ButtonBorderStyle.Solid);
ControlPaint.DrawBorder(g, inner, this.BackColor, ButtonBorderStyle.Solid);
}
else
{
using (var brush = new SolidBrush(Focused ? theme.ComboBoxFocusBackColor : theme.ComboBoxBackColor))
{
if (SelectedIndex == -1)
{
g.FillRectangle(brush, this.ClientRectangle);
}
int arrowWidth = SystemInformation.VerticalScrollBarWidth;
var center = new Point(this.Width - arrowWidth / 2, this.Height / 2);
//Down
Point[] arrow = new[] {
new Point(center.X - 4, center.Y - 2),
new Point(center.X + 4, center.Y - 2),
new Point(center.X, center.Y + 4)
};
g.FillPolygon(theme.GetTextBrush(), arrow);
}
var borderColor = MouseState == MouseState.Hover
? theme.BorderOverColor
: Focused
? theme.BorderFocusColor
: Enabled
? theme.BorderColor
: theme.BorderDisabledColor;
var outer = new Rectangle(0, 0, this.Width, this.Height);
ControlPaint.DrawBorder(g, outer, borderColor, ButtonBorderStyle.Solid);
}
}
ReleaseDC(m.HWnd, dc);
}
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
if (e.Index == -1)
return;
var theme = ThemeManager.Theme;
if (theme == null)
return;
var selected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
|| ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
|| ((e.State & DrawItemState.HotLight) == DrawItemState.HotLight);
using (var backBrush = new SolidBrush(selected ? theme.ComboBoxSelectionBackColor : theme.ComboBoxBackColor))
using (var foreBrush = new SolidBrush(selected ? theme.ComboBoxSelectionForeColor : theme.TextColor))
{
var g = e.Graphics;
g.FillRectangle(backBrush, e.Bounds);
var item = Convert.ToString(FilterItemOnProperty(Items[e.Index]));
g.DrawString(item, Font, foreBrush, e.Bounds);
}
if (theme != null)
{
DrawDropDownBorder(e, theme);
}
}
Однако есть некоторые несоответствия, особенно после выбора элемента, поскольку рисунок, выполненный в WndProc
, переопределен.