• 【C#】分享一个可灵活设置边框的Panel


    ---------------------------更新:2014-05-19---------------------------

    优化了一下逻辑,就是既然可以通过设置BorderSide=None来不显示边框,那么再设计一个BorderMode.None就显得多余,即BorderMode枚举只需要2个元素即可(Single和ThreeD),而与其弄一个只有2个元素的枚举还不如干脆不要这个枚举,改为给PanelEx加一个布尔属性BorderIsSingleMode(之所以这样命名是考虑把与边框相关的属性都以Border开头,方便在设计器中使用),为true则代表单色模式,否则为三维模式,而显不显示、显示哪些边则完全交给BorderSide控制,同时把BorderSide的默认值设为None,即默认不显示边框。修改后的代码如下:

    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace AhDung.Controls
    {
        /// <summary>
        /// 可设置边框样式的Panel
        /// </summary>
        public class PanelEx : Panel
        {
            private Color borderColor;
            private Border3DStyle border3DStyle;
            private ToolStripStatusLabelBorderSides borderSide;
            private bool borderIsSingleMode;
    
            [DefaultValue(true), Description("指定边框是否为单色模式。false代表三维模式")]
            public bool BorderIsSingleMode
            {
                get { return borderIsSingleMode; }
                set
                {
                    if (borderIsSingleMode == value) { return; }
                    borderIsSingleMode = value;
                    this.Invalidate();
                }
            }
    
            [DefaultValue(typeof(Color), "Black"), Description("边框颜色。仅当边框为单色模式时有效")]
            public Color BorderColor
            {
                get { return borderColor; }
                set
                {
                    if (borderColor == value) { return; }
                    borderColor = value;
                    this.Invalidate();
                }
            }
    
            [DefaultValue(Border3DStyle.Etched), Description("边框三维样式。仅当边框为三维模式时有效")]
            public Border3DStyle Border3DStyle
            {
                get { return border3DStyle; }
                set
                {
                    if (border3DStyle == value) { return; }
                    border3DStyle = value;
                    this.Invalidate();
                }
            }
    
            //之所以不直接用Border3DSide是因为这货不被设计器支持,没法灵活选择位置组合
            [DefaultValue(ToolStripStatusLabelBorderSides.None), Description("边框位置。可自由启用各个方位的边框")]
            public ToolStripStatusLabelBorderSides BorderSide
            {
                get { return borderSide; }
                set
                {
                    if (borderSide == value) { return; }
                    borderSide = value;
                    this.Invalidate();
                }
            }
    
            public PanelEx()
            {
                this.borderIsSingleMode = true;
                this.borderColor = Color.Black;
                this.border3DStyle = System.Windows.Forms.Border3DStyle.Etched;
                this.borderSide = ToolStripStatusLabelBorderSides.None;
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                if (this.BorderStyle != System.Windows.Forms.BorderStyle.None
                    || BorderSide == ToolStripStatusLabelBorderSides.None)
                { return; }
    
                using (Graphics g = e.Graphics)
                {
                    //单色模式
                    if (this.BorderIsSingleMode)
                    {
                        using (Pen pen = new Pen(BorderColor))
                        {
                            //若是四条边都启用,则直接画矩形
                            if (BorderSide == ToolStripStatusLabelBorderSides.All)
                            {
                                g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1);
                            }
                            else //否则分别绘制线条
                            {
                                if ((BorderSide & ToolStripStatusLabelBorderSides.Top) == ToolStripStatusLabelBorderSides.Top)
                                {
                                    g.DrawLine(pen, 0, 0, this.Width - 1, 0);
                                }
    
                                if ((BorderSide & ToolStripStatusLabelBorderSides.Right) == ToolStripStatusLabelBorderSides.Right)
                                {
                                    g.DrawLine(pen, this.Width - 1, 0, this.Width - 1, this.Height - 1);
                                }
    
                                if ((BorderSide & ToolStripStatusLabelBorderSides.Bottom) == ToolStripStatusLabelBorderSides.Bottom)
                                {
                                    g.DrawLine(pen, 0, this.Height - 1, this.Width - 1, this.Height - 1);
                                }
    
                                if ((BorderSide & ToolStripStatusLabelBorderSides.Left) == ToolStripStatusLabelBorderSides.Left)
                                {
                                    g.DrawLine(pen, 0, 0, 0, this.Height - 1);
                                }
                            }
                        }
                    }
                    else //三维模式
                    {
                        ControlPaint.DrawBorder3D(g, this.ClientRectangle, this.Border3DStyle, (Border3DSide) BorderSide); //这儿要将ToolStripStatusLabelBorderSides转换为Border3DSide
                    }
                }
            }
        }
    }

    ---------------------------原文:2014-05-14---------------------------

    注:此乃Winform控件,开发环境为.net 2.0

    工作需要,我对自带Panel进行了一下呈现上的扩展,方便设置边框效果。先看效果:

    说明:

    * 只有当原有属性BorderStyle为None时才能应用样式,此时可通过BorderMode设置【不显示、单色、三维】三种边框模式;这是因为BorderStyle为FixedSingle或Fixed3D时,自带边框似乎不属于Panel的一部分,不能控制或清除,我猜应该是底层API负责绘制的,所以唯有在None时才能自由发挥;

    * 无论单色或是三维模式,均可通过BorderSide自由启用/禁用各个方位的边框;

    * 在单色模式下,可通过BorderColor设置边框颜色,此时设置三维样式(Border3DStyle)无效;

    * 在三维模式下,可通过Border3DStyle设置三维样式,此时设置边框颜色(BorderColor)无效;

    代码在此:

    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace AhDung.Controls
    {
        /// <summary>
        /// 边框模式(无、单色、三维)
        /// </summary>
        public enum BorderMode { None, Single, ThreeD }
        
        /// <summary>
        /// 可设置边框样式的Panel
        /// </summary>
        public class PanelEx : Panel
        {
            private Color borderColor;
            private Border3DStyle border3DStyle;
            private ToolStripStatusLabelBorderSides borderSide;
            private BorderMode borderMode;
    
            [DefaultValue(BorderMode.None), Description("边框模式。可设置单色模式或三维模式")]
            public BorderMode BorderMode
            {
                get { return borderMode; }
                set
                {
                    if (borderMode == value) { return; }
                    borderMode = value;
                    this.Invalidate();
                }
            }
    
            [DefaultValue(typeof(Color), "Black"), Description("边框颜色。仅当边框为单色模式时有效")]
            public Color BorderColor
            {
                get { return borderColor; }
                set
                {
                    if (borderColor == value) { return; }
                    borderColor = value;
                    this.Invalidate();
                }
            }
    
            [DefaultValue(Border3DStyle.Etched), Description("边框三维样式。仅当边框为三维模式时有效")]
            public Border3DStyle Border3DStyle
            {
                get { return border3DStyle; }
                set
                {
                    if (border3DStyle == value) { return; }
                    border3DStyle = value;
                    this.Invalidate();
                }
            }
    
            //之所以不直接用Border3DSide是因为这货不被设计器支持,没法灵活选择位置组合
            [DefaultValue(ToolStripStatusLabelBorderSides.All), Description("边框位置。可自由启用各个方位的边框")]
            public ToolStripStatusLabelBorderSides BorderSide
            {
                get { return borderSide; }
                set
                {
                    if (borderSide == value) { return; }
                    borderSide = value;
                    this.Invalidate();
                }
            }
    
            public PanelEx()
            {
                this.borderMode = BorderMode.None;
                this.borderColor = Color.Black;
                this.border3DStyle = System.Windows.Forms.Border3DStyle.Etched;
                this.borderSide = ToolStripStatusLabelBorderSides.All;
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                if (this.BorderStyle != System.Windows.Forms.BorderStyle.None
                    || BorderMode == BorderMode.None
                    || BorderSide == ToolStripStatusLabelBorderSides.None)
                { return; }
    
                using (Graphics g = e.Graphics)
                {
                    //三维模式
                    if (this.BorderMode == BorderMode.ThreeD)
                    {
                        ControlPaint.DrawBorder3D(g, this.ClientRectangle, this.Border3DStyle, (Border3DSide)BorderSide);//这儿要将ToolStripStatusLabelBorderSides转换为Border3DSide
                    }
                    else //单色模式
                    {
                        using (Pen pen = new Pen(BorderColor))
                        {
                            //若是四条边都启用,则直接画矩形
                            if (BorderSide == ToolStripStatusLabelBorderSides.All)
                            {
                                g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1);
                            }
                            else //否则分别绘制线条
                            {
                                if ((BorderSide & ToolStripStatusLabelBorderSides.Top) == ToolStripStatusLabelBorderSides.Top)
                                { g.DrawLine(pen, 0, 0, this.Width - 1, 0); }
    
                                if ((BorderSide & ToolStripStatusLabelBorderSides.Right) == ToolStripStatusLabelBorderSides.Right)
                                { g.DrawLine(pen, this.Width - 1, 0, this.Width - 1, this.Height - 1); }
    
                                if ((BorderSide & ToolStripStatusLabelBorderSides.Bottom) == ToolStripStatusLabelBorderSides.Bottom)
                                { g.DrawLine(pen, 0, this.Height - 1, this.Width - 1, this.Height - 1); }
    
                                if ((BorderSide & ToolStripStatusLabelBorderSides.Left) == ToolStripStatusLabelBorderSides.Left)
                                { g.DrawLine(pen, 0, 0, 0, this.Height - 1); }
                            }
                        }
                    }
                }
            }
        }
    }

    -文毕-

  • 相关阅读:
    Javascript本质第二篇:执行上下文
    Javascript本质第一篇:核心概念
    跨线程委托执行
    .NET中STAThread和MTAThread
    用管道实现流的分支
    Async和Await异步编程的原理
    在.NET中使用管道将输出流转换为输入流
    致木兄的一封信
    完整打造一个多功能音乐播放器项目(初步设想跟酷狗类似)
    新冠疫情下各大网站的变化
  • 原文地址:https://www.cnblogs.com/ahdung/p/3728314.html
Copyright © 2020-2023  润新知