WinForm删除边框、圆角边框

WinForm删除边框、圆角边框

WinForm删除边框

最近使用WinForm做界面美化,需要修改边框样式,但是原生控件边框样式难以扩展。上网没有搜到满意的边框样式修改资料,自行解决后记录下。

主要代码如下

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    //重绘消息WM_PAINT
    if (m.Msg == 0xF)
    {
        base.WndProc(ref m);

        //获取设备环境
        IntPtr hDC = GetWindowDC(m.HWnd);
        if (hDC != IntPtr.Zero)
        {
            //获取画布
            Graphics g = Graphics.FromHdc(hDC);

            //消锯齿
            g.SmoothingMode = SmoothingMode.AntiAlias;

            //边框路径
            GraphicsPath borderPath = CreateBorderPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), Radius * 2);   //新边框路径
            borderPath.AddRectangle(new Rectangle(0, 0, this.Width - 1, this.Height - 1));  //原边框路径
            borderPath.CloseAllFigures();   //封闭路径

            //使用背景色覆盖边框区域
            g.DrawPath(new Pen(BackColor), borderPath); //覆盖边框
            g.FillPath(new SolidBrush(BackColor), borderPath);  //覆盖边框包含区域

            //绘制新边框、如果只是删除边框的话,不绘制即可
            g.DrawPath(new Pen(CurrentBorderColor), CreateBorderPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), Radius * 2));

            g.Dispose();
            ReleaseDC(m.HWnd, hDC);
        }
    }
    else
    {
        base.WndProc(ref m);
    }
}

基本思想就是在界面重绘后,使用背景色覆盖边框区域,再重新绘制边框。下面是以此实现的圆角时间选择控件,以供参考

public class RoundedDateTimePicker : DateTimePicker
{
    /// <summary>
    /// 当前边框颜色
    /// </summary>
    private Color CurrentBorderColor;
    /// <summary>
    /// 边框颜色
    /// </summary>
    public Color BorderColor { get; set; } = Color.FromArgb(230, 230, 230);
    /// <summary>
    /// 边框颜色_鼠标进入控件
    /// </summary>
    public Color EnterBorderColor { get; set; } = Color.FromArgb(0, 0, 0);
    /// <summary>
    /// 边框颜色_获取焦点
    /// </summary>
    public Color FocusBorderColor { get; set; } = Color.FromArgb(62, 123, 250);
    /// <summary>
    /// 边框圆角半径
    /// </summary>
    public int Radius { get; set; } = 8;
    public RoundedDateTimePicker()
    {
        InitializeComponent();

        this.CurrentBorderColor = this.BorderColor;
        
    }
    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        //重绘消息WM_PAINT
        if (m.Msg == 0xF)
        {
            base.WndProc(ref m);

            //获取设备环境
            IntPtr hDC = GetWindowDC(m.HWnd);
            if (hDC != IntPtr.Zero)
            {
                //获取画布
                Graphics g = Graphics.FromHdc(hDC);

                //消锯齿
                g.SmoothingMode = SmoothingMode.AntiAlias;

                //边框路径
                GraphicsPath borderPath = CreateBorderPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), Radius * 2);   //新边框路径
                borderPath.AddRectangle(new Rectangle(0, 0, this.Width - 1, this.Height - 1));  //原边框路径
                borderPath.CloseAllFigures();   //封闭路径

                //使用背景色覆盖边框区域
                g.DrawPath(new Pen(BackColor), borderPath); //覆盖边框
                g.FillPath(new SolidBrush(BackColor), borderPath);  //覆盖边框包含区域

                //绘制新边框
                g.DrawPath(new Pen(CurrentBorderColor), CreateBorderPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), Radius * 2));

                g.Dispose();
                ReleaseDC(m.HWnd, hDC);
            }
        }
        else
        {
            base.WndProc(ref m);
        }
    }

    [DllImport("User32.dll")]
    private static extern IntPtr GetWindowDC(IntPtr hWnd);

    [DllImport("User32.dll")]
    private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

    private void InitializeComponent()
    {
        this.SuspendLayout();
        // 
        // RoundedDateTimePicker
        // 
        this.Enter += new System.EventHandler(this.OnEntered);
        this.Leave += new System.EventHandler(this.OnLeft);
        this.MouseEnter += new System.EventHandler(this.OnMouseEntered);
        this.MouseLeave += new System.EventHandler(this.OnMouseLeft);
        this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove);
        this.ResumeLayout(false);

    }
    private GraphicsPath CreateBorderPath(Rectangle rect, int diameter)
    {
        GraphicsPath path = new GraphicsPath();
        path.AddArc(rect.Left, rect.Top, diameter, diameter, 180, 90);
        path.AddLine(rect.Left + diameter, rect.Top, rect.Right - diameter, rect.Top);
        path.AddArc(rect.Right - diameter, rect.Top, diameter, diameter, 270, 90);
        path.AddLine(rect.Right, rect.Top + diameter, rect.Right, rect.Bottom - diameter);
        path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);
        path.AddLine(rect.Right - diameter, rect.Bottom, rect.Left + diameter, rect.Bottom);
        path.AddArc(rect.Left, rect.Bottom - diameter, diameter, diameter, 90, 90);
        path.AddLine(rect.Left, rect.Bottom - diameter, rect.Left, rect.Top + diameter);
        path.CloseAllFigures();
        return path;
    }
    private void RefreshBorder()
    {
        if (this.Focused)
            this.CurrentBorderColor = FocusBorderColor;
        else if (this.RectangleToScreen(this.ClientRectangle).Contains(MousePosition))
            this.CurrentBorderColor = EnterBorderColor;
        else
            this.CurrentBorderColor = BorderColor;
    }
    private void OnMouseEntered(object sender, EventArgs e)
    {
        this.RefreshBorder();
    }
    private void OnMouseLeft(object sender, EventArgs e)
    {
        this.RefreshBorder();
    }
    private void OnEntered(object sender, EventArgs e)
    {
        this.RefreshBorder();
    }
    private void OnLeft(object sender, EventArgs e)
    {
        this.RefreshBorder();
    }
    private void OnMouseMove(object sender, MouseEventArgs e)
    {
        this.RefreshBorder();
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值