2014-01-03 4 views
5

Я использую более темный стиль для нескольких полей формы C# WinForms. Выпадающий в частности похож на это:Пользовательские границы полей combobox мерцают

enter image description here

Я использую этот код из этого стека ответа: Combobox borderstyle

К сожалению, у меня возникли проблемы с мерцанием границами. Когда я mouseenter или mouseover на combobox, он будет мерцать быстро с белой рамкой.

Есть ли способ исправить эту проблему? Я пробовал использовать DoubleBuffer, но это не облегчает проблему.

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Windows.Forms; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Runtime.InteropServices; 

namespace FlattenCombo 
{ 
    public class FlattenCombo : ComboBox 
    { 
     private Brush BorderBrush = new SolidBrush(SystemColors.WindowFrame); 
     private Brush ArrowBrush = new SolidBrush(SystemColors.ControlText); 
     private Brush DropButtonBrush = new SolidBrush(SystemColors.Control); 

     private Color _ButtonColor = SystemColors.Control; 
     public Color ButtonColor 
     { 
      get { return _ButtonColor; } 
      set 
      { 
       _ButtonColor = value; 
       DropButtonBrush = new SolidBrush(this.ButtonColor); 
       this.Invalidate(); 
      } 
     } 

     private Color _borderColor = Color.Black; 
     private ButtonBorderStyle _borderStyle = ButtonBorderStyle.Solid; 
     //private static int WM_PAINT = 0x000F; 

     [Category("Appearance")] 
     public Color BorderColor 
     { 
      get { return _borderColor; } 
      set 
      { 
       _borderColor = value; 
       this.Invalidate(); // causes control to be redrawn 
      } 
     } 

     [Category("Appearance")] 
     public ButtonBorderStyle BorderStyle 
     { 
      get { return _borderStyle; } 
      set 
      { 
       _borderStyle = value; 
       this.Invalidate(); 
      } 
     } 

     protected override void WndProc(ref Message m) 
     { 
      base.WndProc(ref m); 



      /*if (m.Msg == WM_PAINT) 
      { 
       Graphics g = Graphics.FromHwnd(Handle); 
       Rectangle bounds = new Rectangle(0, 0, Width, Height); 
       ControlPaint.DrawBorder(g, bounds, _borderColor, _borderStyle); 
      }*/ 

      switch (m.Msg) 
      { 
       case 0xf: 
        //Paint the background. Only the borders 
        //will show up because the edit 
        //box will be overlayed 
        //Graphics g = Graphics.FromHwnd(Handle); 
        Graphics g = this.CreateGraphics(); 
        Rectangle bounds = new Rectangle(0, 0, Width, Height); 
        ControlPaint.DrawBorder(g, bounds, _borderColor, _borderStyle); 

        //Pen p = new Pen(Color.White, 2); 
        //g.FillRectangle(BorderBrush, this.ClientRectangle); 

        //Draw the background of the dropdown button 
        Rectangle rect = new Rectangle(this.Width - 18, 0, 18, this.Height); 
        g.FillRectangle(DropButtonBrush, rect); 

        //Create the path for the arrow 
        System.Drawing.Drawing2D.GraphicsPath pth = new System.Drawing.Drawing2D.GraphicsPath(); 
        PointF TopLeft = new PointF(this.Width - 13, (this.Height - 5)/2); 
        PointF TopRight = new PointF(this.Width - 6, (this.Height - 5)/2); 
        PointF Bottom = new PointF(this.Width - 9, (this.Height + 2)/2); 
        pth.AddLine(TopLeft, TopRight); 
        pth.AddLine(TopRight, Bottom); 

        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 

        //Determine the arrow's color. 
        if (this.DroppedDown) 
        { 
         ArrowBrush = new SolidBrush(SystemColors.HighlightText); 
        } 
        else 
        { 
         ArrowBrush = new SolidBrush(SystemColors.ControlText); 
        } 

        //Draw the arrow 
        g.FillPath(ArrowBrush, pth); 

        g.Dispose(); 

        break; 
      } 
     } 

     //Override mouse and focus events to draw 
     //proper borders. Basically, set the color and Invalidate(), 
     //In general, Invalidate causes a control to redraw itself. 
     //#region "Mouse and focus Overrides" 
     protected override void OnMouseEnter(System.EventArgs e) 
     { 
      base.OnMouseEnter(e); 
      //BorderBrush = new SolidBrush(SystemColors.Highlight); 
      //EnableDoubleBuffering(); 
      this.Invalidate(); 
     } 

     protected override void OnMouseLeave(System.EventArgs e) 
     { 
      base.OnMouseLeave(e); 
      /*if (this.Focused) 
       return;*/ 
      BorderBrush = new SolidBrush(SystemColors.WindowFrame); 
      //EnableDoubleBuffering(); 
      this.Invalidate(); 
     } 

     protected override void OnLostFocus(System.EventArgs e) 
     { 
      base.OnLostFocus(e); 
      //BorderBrush = new SolidBrush(SystemColors.Window); 
      //EnableDoubleBuffering(); 
      this.Invalidate(); 
     } 

     protected override void OnGotFocus(System.EventArgs e) 
     { 
      base.OnGotFocus(e); 
      BorderBrush = new SolidBrush(SystemColors.WindowFrame); 
      //EnableDoubleBuffering(); 
      this.Invalidate(); 
     } 

     protected override void OnMouseHover(System.EventArgs e) 
     { 
      base.OnMouseHover(e); 
      BorderBrush = new SolidBrush(SystemColors.WindowFrame); 
      //EnableDoubleBuffering(); 
      this.Invalidate(); 
     } 
     //#endregion 
    } 
} 

ответ

5

Короткая версия: добавить к вашей Form значительно уменьшить мерцание. Я пробовал использовать 7-8 из вашего измененного flattenCombo, и есть большая разница.

protected override CreateParams CreateParams 
{ 
    get 
    { 
     CreateParams cp = base.CreateParams; 
     cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED 
     return cp; 
    } 
} 

Long Version: How to fix the flickering in User controls. Отличный пост, также объясняет другие трюки.

+0

Красивая! Это хорошо походило на мерцание. Спасибо за ссылку на этот пост. – Spencer

Смежные вопросы