我需要一个可以改变边框颜色的 Panel,所以自定义了下面的这样一个控件:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Text;
using System.Windows.Forms;namespace BorderPanel
{
    public partial class BorderPanel : Panel
    {
        private bool isNeedBorder = false;   // 是否需要边框
        private Color borderColor = Color.Black;   // 边框颜色
        private bool isNeedSmooth = false;   // 圆滑倒角
        private int smoothRadius = 8;        // 倒角半径        public BorderPanel()
        {
            InitializeComponent();
        }        # region 自定义属性
        [Browsable(true)]
        [Description("是否需要特殊边框")]
        public bool IsNeedBorder
        {
            get { return isNeedBorder; }
            set
            {
                if (value)
                {
                    this.BorderStyle = BorderStyle.None;
                }
                isNeedBorder = value;
            }
        }        [Browsable(true)]
        [Description("边框颜色")]
        public Color BorderColor
        {
            get { return borderColor; }
            set { borderColor = value; }
        }        [Browsable(true)]
        [Description("圆滑倒角")]
        public bool IsNeedSmooth
        {
            get { return isNeedSmooth; }
            set
            {
                if (value)
                {
                    this.BorderStyle = BorderStyle.None;
                    setRegion();
                }
                else
                {
                    this.Region = null;
                }
                isNeedSmooth = value;
            }
        }        [Browsable(true)]
        [Description("平滑半径")]
        public int SmoothRadius
        {
            get { return smoothRadius; }
            set
            {
                smoothRadius = value;
                smoothRadius = smoothRadius * 2 <= Width ? smoothRadius : Width / 2;
                smoothRadius = smoothRadius * 2 <= Height ? smoothRadius : Height / 2;
            }
        }
        # endregion        # region 保护方法        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (BorderStyle == BorderStyle.None)
            {
                Pen myPen = new Pen(borderColor);
                if (IsNeedBorder)
                {
                    if (!isNeedSmooth)
                    {
                        e.Graphics.Clear(this.BackColor); //按道理这句话应该可以清除原边框,可是为什么改变大小后原边框还在?
                        e.Graphics.DrawRectangle(myPen, 0, 0, Width - 1, Height - 1);
                    }
                    else
                    {
                        e.Graphics.DrawArc(myPen, 1, 1, smoothRadius * 2, smoothRadius * 2, 180f, 90f);
                        e.Graphics.DrawLine(myPen, new Point(smoothRadius + 1, 1), new Point(Width - smoothRadius - 1, 1));
                        e.Graphics.DrawArc(myPen, Width - smoothRadius * 2 - 1, 1, smoothRadius * 2, smoothRadius * 2, -90f, 90f);
                        e.Graphics.DrawLine(myPen, new Point(Width - 1, smoothRadius + 1), new Point(Width - 1, Height - smoothRadius - 1));
                        e.Graphics.DrawArc(myPen, Width - smoothRadius * 2 - 1, Height - smoothRadius * 2 - 1, smoothRadius * 2, smoothRadius * 2, 0f, 90f);
                        e.Graphics.DrawLine(myPen, new Point(Width - smoothRadius - 1, Height - 1), new Point(smoothRadius + 1, Height - 1));
                        e.Graphics.DrawArc(myPen, 1, Height - smoothRadius * 2 - 1, smoothRadius * 2, smoothRadius * 2, 90f, 90f);
                        e.Graphics.DrawLine(myPen, new Point(1, Height - smoothRadius - 1), new Point(1, smoothRadius + 1));
                    }
                }
            }
        }        protected override void OnResize(EventArgs eventargs)
        {
            base.OnResize(eventargs);
            if (isNeedSmooth)
            {
                setRegion();
            }
        }        # endregion        # region 私有方法        /// <summary>
        /// 设置region
        /// </summary>
        private void setRegion()
        {
            GraphicsPath graphicsPath = new GraphicsPath();
            graphicsPath.AddArc(0, 0, smoothRadius * 2, smoothRadius * 2, 180f, 90f);
            graphicsPath.AddLine(new Point(smoothRadius, 0), new Point(Width - smoothRadius, 0));
            graphicsPath.AddArc(Width - smoothRadius * 2, 0, smoothRadius * 2, smoothRadius * 2, -90f, 90f);
            graphicsPath.AddLine(new Point(Width, smoothRadius), new Point(Width, Height - smoothRadius));
            graphicsPath.AddArc(Width - smoothRadius * 2, Height - smoothRadius * 2, smoothRadius * 2, smoothRadius * 2, 0f, 90f);
            graphicsPath.AddLine(new Point(Width - smoothRadius, Height), new Point(Width - smoothRadius, Height));
            graphicsPath.AddArc(0, Height - smoothRadius * 2, smoothRadius * 2, smoothRadius * 2, 90f, 90f);
            graphicsPath.AddLine(new Point(0, Height - smoothRadius), new Point(0, smoothRadius));
            this.Region = new Region(graphicsPath);
        }        # endregion        private void InitializeComponent()
        {
            this.SuspendLayout();
            this.ResumeLayout(false);        }
    }
}在使用过程中,确实可以使边框的颜色改变了。可是当我用 Panel.Height = ??? 后,原来的边框并没有清除掉,这就使得 Panel 的中间多了一条线。上面的代码中红色的部分为什么没有起作用呢?请高人指教一下,谢谢。

解决方案 »

  1.   

    Pen myPen = new Pen(borderColor); 
                    if (IsNeedBorder) 
                    { 
    //这句话放到外面
                            e.Graphics.Clear(this.BackColor); //按道理这句话应该可以清除原边框,可是为什么改变大小后原边框还在? 
    //你也可以,或其实方式清除原来的边线。e.Graphics.Fill();
                        if (!isNeedSmooth) 
                        {                         e.Graphics.DrawRectangle(myPen, 0, 0, Width - 1, Height - 1); 
                        } 
                        else 
                        { 
                            e.Graphics.DrawArc(myPen, 1, 1, smoothRadius * 2, smoothRadius * 2, 180f, 90f); 
                            e.Graphics.DrawLine(myPen, new Point(smoothRadius + 1, 1), new Point(Width - smoothRadius - 1, 1)); 
                            e.Graphics.DrawArc(myPen, Width - smoothRadius * 2 - 1, 1, smoothRadius * 2, smoothRadius * 2, -90f, 90f); 
                            e.Graphics.DrawLine(myPen, new Point(Width - 1, smoothRadius + 1), new Point(Width - 1, Height - smoothRadius - 1)); 
                            e.Graphics.DrawArc(myPen, Width - smoothRadius * 2 - 1, Height - smoothRadius * 2 - 1, smoothRadius * 2, smoothRadius * 2, 0f, 90f); 
                            e.Graphics.DrawLine(myPen, new Point(Width - smoothRadius - 1, Height - 1), new Point(smoothRadius + 1, Height - 1)); 
                            e.Graphics.DrawArc(myPen, 1, Height - smoothRadius * 2 - 1, smoothRadius * 2, smoothRadius * 2, 90f, 90f); 
                            e.Graphics.DrawLine(myPen, new Point(1, Height - smoothRadius - 1), new Point(1, smoothRadius + 1)); 
                        } 
                    } 
      

  2.   

    首先,谢谢楼上的回答。
    但是这句话放外面并没有什么改变,因为 isNeedSmooth = false。我也试过按你说的放外面了,一样的。
    还有后面那句 e.Graphics.Fill(); e.Graphics 没有 Fill() 方法……
      

  3.   


        public partial class BorderPanel : Panel
        {
            private bool isNeedBorder = false;   // 是否需要边框 
            private Color borderColor = Color.Black;   // 边框颜色 
            private int smoothRadius = 8;        // 倒角半径         public BorderPanel()
            {
                this.SetStyle(ControlStyles.UserPaint, true);
                this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
                this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
                this.SetStyle(ControlStyles.ResizeRedraw, true);
            }        [Browsable(true)]
            [Description("是否需要特殊边框")]
            public bool IsNeedBorder
            {
                get { return isNeedBorder; }
                set
                {
                    if (value)
                    {
                        this.BorderStyle = BorderStyle.None;
                    }
                    isNeedBorder = value;                this.Invalidate();
                }
            }        [Browsable(true)]
            [Description("边框颜色")]
            public Color BorderColor
            {
                get { return borderColor; }
                set { borderColor = value; this.Invalidate(); }
            }        [Browsable(true)]
            [Description("平滑半径")]
            public int SmoothRadius
            {
                get { return smoothRadius; }
                set
                {
                    smoothRadius = value;
                    smoothRadius = smoothRadius * 2 <= Width ? smoothRadius : Width / 2;
                    smoothRadius = smoothRadius * 2 <= Height ? smoothRadius : Height / 2;                this.Invalidate();
                }
            }        protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                if (BorderStyle != BorderStyle.None)
                    return;            if (IsNeedBorder)
                {
                    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;                e.Graphics.Clear(this.BackColor);                Pen myPen = new Pen(borderColor);                GraphicsPath gp = new GraphicsPath();
                    gp.AddArc(0, 0, smoothRadius, smoothRadius, 180, 90);
                    gp.AddArc(Width - 2 - smoothRadius, 0, smoothRadius, smoothRadius, 270, 90);
                    gp.AddArc(Width - 2 - smoothRadius, Height - 2 - smoothRadius, smoothRadius, smoothRadius, 0, 90);
                    gp.AddArc(0, Height - 2 - smoothRadius, smoothRadius, smoothRadius, 90, 90);
                    gp.CloseFigure();
                    e.Graphics.DrawPath(myPen, gp);                gp.Dispose();
                    myPen.Dispose();
                }
            }        protected override void OnResize(EventArgs eventargs)
            {
                base.OnResize(eventargs);            GraphicsPath gp = new GraphicsPath();
                gp.AddArc(0, 0, smoothRadius, smoothRadius, 180, 90);
                gp.AddArc(Width - 1 - smoothRadius, 0, smoothRadius, smoothRadius, 270, 90);
                gp.AddArc(Width - 1 - smoothRadius, Height - 1 - smoothRadius, smoothRadius, smoothRadius, 0, 90);
                gp.AddArc(0, Height - 1 - smoothRadius, smoothRadius, smoothRadius, 90, 90);
                gp.CloseFigure();            Region region = new Region(gp);
                this.Region = region;            gp.Dispose();
            }
      

  4.   

    e.Graphics.Clear(this.BackColor);可以去掉。
      

  5.   

    protected override void OnResize(EventArgs eventargs)
    {
         base.OnResize(eventargs);
         if (isNeedSmooth)
         {
              setRegion();
         }
    }
    改为
    protected override void OnResize(EventArgs eventargs)
    {
         base.OnResize(eventargs);
         if (isNeedSmooth)
         {
              setRegion();
         }
         base.Refresh();
    }
    就可以了。