自定义组合框边界闪烁

 依然-狠幸福 发布于 2023-02-06 20:11

我在一些c#WinForms表单字段中使用了较暗的样式.组合框特别类似于:

在此输入图像描述

我正在使用此Stack答案中的代码:Combobox borderstyle

不幸的是,我遇到了闪烁边框的问题.当我将鼠标放入或鼠标悬停在组合框上时,它将以白色边框快速闪烁.

有没有办法解决这个问题?我尝试过使用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
    }
}

Vland.. 5

简短版本:将此添加到您Form的大大减少闪烁.我已经尝试过使用7-8的修改版本flattenCombo,这有很大的不同.

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

长版:如何修复用户控件中的闪烁.伟大的帖子,也解释了别人的伎俩.

1 个回答
  • 简短版本:将此添加到您Form的大大减少闪烁.我已经尝试过使用7-8的修改版本flattenCombo,这有很大的不同.

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

    长版:如何修复用户控件中的闪烁.伟大的帖子,也解释了别人的伎俩.

    2023-02-06 20:13 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有