OwnerDrawn时如何在ComboBox中显示所选项目?

时间:2019-06-24 07:44:12

标签: c# visual-studio winforms

我正在绘制一个组合框,并且已覆盖OnPaintOnDrawItem。到目前为止,一切正常。

但是,当我从列表中选择一个项目并关闭列表后,所选项目不会显示在组合框的文本部分。

我需要处理哪些消息才能在此处绘制项目?

我在处理WM_PAINT时添加了以下内容:

if (SelectedIndex == -1)
{
    g.FillRectangle(brush, this.ClientRectangle);
}

我应该在WndProcOnPaint中绘制图形吗?

更新:

这是WndProcOnDrawItem事件的代码。在WndProc中,我绘制了控件的表面(文本部分,按钮,边框)。我在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中绘制的图形会被覆盖。

0 个答案:

没有答案