0

I am working on a set of UI Elements currently and the ComboBox is giving me a hard time.

My goal is to paint a 1px border around the element which will change color when the mouse hovers over it.

I used the WndProc() Method to react to the WM_PAINT Message and draw the border:

protected override void WndProc(ref Message m)
{
        if (m.Msg == (int)WindowsMessages.Win32Messages.WM_PAINT)
        {
            base.WndProc(ref m);
            if (hovered || Focused)
            {
                //Paint frame with hovered color when being hovered over
                PaintHelper.PaintFrame(this, _frameColorHovered, _frameWidth);
            }
            else
            {
                //Paint frame with standart color
                PaintHelper.PaintFrame(this, _frameColor, _frameWidth);
            }

        }
        .
        .
        .
}

Paint helper method looks as follows:

public static void PaintFrame(Control target, Color color, int frameWidth)
{
        IntPtr dc = GetWindowDC(target.Handle);
        using (Graphics g = Graphics.FromHdc(dc))
        {
            using (Pen p = new Pen(color, frameWidth))
                g.DrawRectangle(p, frameWidth / 2, frameWidth / 2, target.Width - frameWidth, target.Height - frameWidth);
        }
 }

So far so good but the border keeps flickering when the mouse moves out or inside of the the Elements bounds! I did some research but everyone uses the UserPaint flag which is not an option for me.

So: Is there any way to remove the flickering without painting the whole control myself?

  • I don't know whether it is related, but you don't call ReleaseDC in PaintFrame function. Also, try to use WM_NCPAINT instead of WM_PAINT. – Alex F Jun 04 '18 at 13:04
  • NCPAINT does not work because I am not painting in non-client area. So WM_PAINT would just paint over my border ifI would paint it in NCPAINT. – Jan Hildebrandt Jun 04 '18 at 13:11
  • 1
    A more sensible way to do this is to draw a rectangle *around* the control instead of trying to paint on top of it. You'd use its Parent's Paint event. You can try [this trick](https://stackoverflow.com/a/89125/17034) to suppress the inevitable flicker you get now. – Hans Passant Jun 04 '18 at 13:54
  • I've posted something like this (the answer has not been accepted though): [Changing the border color of a Combobox on focus](https://stackoverflow.com/questions/49302435/changing-the-border-color-of-a-combobox-on-focus?answertab=active#tab-top). The custom control registers the `Enter` and `Leave` events, but you can change them to `MouseEnter` and `MouseLeave` without any modificaton to the code. You can drop the custom control onto a Form and try it out. – Jimi Jun 04 '18 at 15:18
  • Thank you for your suggestions but neither of them are working for me. @HansPassant turning that flag on seems to change nothing in my case. – Jan Hildebrandt Jun 05 '18 at 09:05
  • @Jimi I thought about that as well. The problem is you can still see parts of the rounded border because we are not painting on top of it. That looks weird and not solid. – Jan Hildebrandt Jun 05 '18 at 09:07

0 Answers0