zoukankan      html  css  js  c++  java
  • C#皮肤美化:制作类似QQ带光晕的文本框Textbox

    本篇C#皮肤美化实例将制作一个类似QQ的带光晕的文本框Textbox,还是先看看最终的效果图(和QQ登陆中的输入框效果差不多):查看 TextboxEx效果

    效果说明: 1.实现了水印的效果 2.实现了鼠标移上去的时候周围产生辉光 3.输入前端可以设置图片。

    实现辉光效果

        整体说明:

              前面显示的那个图片我采用的是一个picturebox,当然如果你愿意也可以自己画(后续的“button再探讨”中就采用的是自己画的方式)。图片后面的输入文本框采用的是textbox控件,这样一来就避免了许多绘制textbox的麻烦(我一开始打算自己绘制用户输入的字符的,不过发现不理想)。然后边框和辉光都是画出来的。

      具体实现:

     先抛开水印不说。最重要的就是重写的OnPaint方法,如下:

    protected override void OnPaint(PaintEventArgs e)
            {
                Graphics g = e.Graphics;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;
    
                CalculateSizeAndPosition();
                Draw(e.ClipRectangle, e.Graphics);
    
                base.OnPaint(e);
            }

    可以看出里面调用了两个方法,做过前面窗体换肤的可能对这个不陌生。就是绘画之前计算好所有的位置大小信息,然后再调用draw画出来。那么这次的calculateSizeAndPosition又做了什么呢?2点!1.判断是否有前端图片需要显示,2.判断是否处于multiline模式。代码如下:

    private void CalculateSizeAndPosition()
            {
                if (ForeImage != null)
                {
                    //图片大小固定为16
                    pic.Height = pic.Width = 16;
                    pic.Top = pic.Left = 3;
                    txt.Width = Width - pic.Width - 12;
                    txt.Location = new Point(16 + 3 + 3, 6);
                }
                else
                {
                    pic.Left = -40;  //隐藏图片
                      txt.Width = Width - 9;
                    txt.Location = new Point(3, 6);
                }
    
                //单行
                if (!txt.Multiline)
                {
                    Height = txt.Height + 9;
                }
                else
                {
                    txt.Height = Height - 9;  //如果是多行则设置实际里面的输入文本框的高度
                }
            }

    当所有的东西都计算好了,我们就可以安心的拿起我们的画笔竟然绘画了。先画什么?再画什么?请看代码:

    private void Draw(Rectangle rectangle, Graphics g)
            {
    
                #region 画背景
                using (SolidBrush backgroundBrush = new SolidBrush(Color.White))
                {
                    g.FillRectangle(backgroundBrush, 2, 2, this.Width - 5, this.Height -4);
                }
                #endregion
    
                #region 画阴影(外边框)
    
                Color drawShadowColor = _shadowColor;
                if (!_isFouse)    //判断是否获得焦点
                {
                    drawShadowColor = Color.Transparent;
                }
                using (Pen shadowPen = new Pen(drawShadowColor))
                {
                    if (_radius == 0)
                    {
                        g.DrawRectangle(shadowPen, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1));
                    }
                    else
                    {
                        g.DrawPath(shadowPen, DrawHelper.DrawRoundRect(rectangle.X, rectangle.Y, rectangle.Width - 2, rectangle.Height - 1, _radius));
                    }
                }
                #endregion
    
                #region 画边框
                using (Pen borderPen = new Pen(_borderColor))
                {
                    if (_radius == 0)
                    {
                        g.DrawRectangle(borderPen, new Rectangle(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 3));
                    }
                    else
                    {
                        g.DrawPath(borderPen, DrawHelper.DrawRoundRect(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 2, _radius));
                    }
                }
                #endregion
            }

    在这个方法里面主要画了三个东西,大家看注释也知道了,分别是:背景,边框,辉光。要注意的就是这里面的微小距离要设置好,我也改了好几次才设置正确。在画边框和辉光的时候,因为实现了圆角边框所以要对圆角度进行判断。

    现在绘画的方法也做好了,接下来就是出发重绘的事件了。不然它也不会自动帮你绘画啊^_^。显然当鼠标移上去和移出去的时候需要重新绘画。那我们就在下面几个方法中引发重绘事件:

     private void TextBoxEx2_MouseEnter(object sender, EventArgs e)
            {
                _isFouse = true;
                this.Invalidate();
            }
    
            private void TextBoxEx2_MouseLeave(object sender, EventArgs e)
            {
                _isFouse = false;
                this.Invalidate();
            }

    代码很简单,不解释。

    基本上面的做好了,大部分就完成了。下面我们完成水印的功能。至此,textbox美化讲解完毕,希望对你有帮助

    实现水印效果

          水印我是这样子实现的:当用户离开输入焦点的时候检测当前用户有没有输入字符,如果没有输入则改变输入框的颜色(灰色),然后看起来就像是水印的感觉啦。我们专门写了一个函数来设置水印,如下:

    private void SetWaterMark()
            {
                if (_waterMark != null && (txt.Text == " " || txt.Text == @" " + WaterMark))  //用户没有输入
                {    
                    txt.ForeColor = _waterMarkColor;
                    txt.Text = @" " + WaterMark;
                }
                else
                {
                    txt.ForeColor = ForeColor;
                }
            }

    然后在什么地方调用呢?刚才上面也已经说了当用户离开焦点的时候判断,不过用户获得输入焦点的时候我们还要设置一下,如果当前的文本时水印的话就清空文本等待输入:

    private void Txt_GotFocus(object sender, EventArgs e)
            {
                if (txt.Text == @" " + WaterMark)
                {
                    //获得焦点,切换正常文字等待填写
                    txt.ForeColor = ForeColor;
                    txt.Text = " ";
                }
            }
    
            private void Txt_LostFocus(object sender, EventArgs e)
            {
                SetWaterMark();
            }

    这里还有一点需要注意的是,在pageload里面我们也需要调用一下setwatermark方法,不然它一开始是不会显示滴!

    源代码快照

    namespace QLFUI
    {
        public partial class TextBoxEx : UserControl
        {
            #region - 变量 -
    
            private Color _borderColor = Color.FromArgb(166, 208, 226);
            private Color _shadowColor = Color.FromArgb(175, 212, 228);
            private Image _foreImage = null;
            private bool _isFouse = false;
            private Color _backColor = Color.Transparent;
            private string _waterMark = null;
            private Color _waterMarkColor = Color.Silver;
            private Color _foreColor = Color.Black;
            private int _radius = 3;
    
            #endregion
    
            #region - 属性 -
    
            [Category("QLFUI"), Description("边框颜色,BorderStyle为FixedSingle有效")]
            public Color BorderColor
            {
                get { return _borderColor; }
                set
                {
                    _borderColor = value;
                    this.Invalidate();
                }
            }
    
            [Category("QLFUI"), Description("边框阴影颜色,BorderStyle为FixedSingle有效")]
            public Color ShadowColor
            {
                get { return _shadowColor; }
                set
                {
                    _shadowColor = value;
                    this.Invalidate();
                }
            }
    
            [Category("QLFUI"), Description("显示的前端的图片")]
            public Image ForeImage
            {
                get { return pic.Image; }
                set
                {
                    _foreImage = value;
                    pic.Image = _foreImage;
                    Invalidate();
                }
            }
    
            [Category("QLFUI"), Description("文字")]
            public string Caption
            {
                get
                {
                    return txt.Text;
                }
                set
                {
                    txt.Text = value;
                    SetWaterMark();
                    Invalidate();
                } 
            }
    
            [Category("行为"), Description("是否多行显示")]
            public bool Multiline
            {
                get { return txt.Multiline; }
                set
                {
                    txt.Multiline = value;
                }
            }
    
            [Category("行为"), Description("是否以密码形式显示字符")]
            public bool UseSystemPasswordChar
            {
                get { return txt.UseSystemPasswordChar; }
                set
                {
                    txt.UseSystemPasswordChar = value;
                }
            }
    
            [Category("QLFUI"), Description("水印文字")]
            public string WaterMark
            {
                get { return _waterMark; }
                set
                {
                    _waterMark = value;
                    Invalidate();
                }
            }
    
            [Category("QLFUI"), Description("水印颜色")]
            public Color WaterMarkColor
            {
                get { return _waterMarkColor; }
                set
                {
                    _waterMarkColor = value;
                    Invalidate();
                }
            }
    
            #region 需要被隐藏的属性
    
            [Browsable(false)]
            public new BorderStyle BorderStyle
            {
                get { return BorderStyle.None; }
            }
    
            [Browsable(false)]
            public new Color BackColor
            {
                get { return base.BackColor; }
                set { base.BackColor = value; }
            }
    
            [Browsable(false)]
            public new Image BackgroundImage
            {
                get { return null; }
            }
    
            [Browsable(false)]
            public new ImageLayout BackgroundImageLayout
            {
                get { return base.BackgroundImageLayout; }
                set { base.BackgroundImageLayout = value; }
            }
    
            #endregion
    
            [Category("QLFUI"), Description("边角弯曲的角度(1-10),数值越大越弯曲")]
            public int Radius
            {
                get { return _radius; }
                set
                {
                    if (value > 10)
                    {
                        value = 10;
                    }
                    if (value < 0)
                    {
                        value = 0;
                    }
                    _radius = value;
                    this.Invalidate();
                }
            }
    
            [Browsable(true)]
            [Category("外观"), Description("文本颜色")]
            public new Color ForeColor
            {
                get { return _foreColor; }
                set { _foreColor = value; }
            }
    
            [Browsable(true)]
            [Category("外观"), Description("鼠标形状")]
            public new Cursor Cursor
            {
                get { return txt.Cursor; }
                set { txt.Cursor = value; }
            }
    
            [Category("行为"), Description("自动提示方式")]
            public AutoCompleteMode AutoCompleteMode
            {
                get { return txt.AutoCompleteMode; }
                set { txt.AutoCompleteMode = value; }
            }
    
            [Category("行为"), Description("自动提示类型")]
            public AutoCompleteSource AutoCompleteSource
            {
                get { return txt.AutoCompleteSource; }
                set { txt.AutoCompleteSource = value; }
            }
    
            #endregion
    
            #region - 构造函数 -
    
            public TextBoxEx()
            {
                SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
                InitializeComponent();
    
                BackColor = Color.Transparent;
    
                //下面的图片和文本框的大小位置必须设置,否则首次启动时
                //会出现莫名其妙的断痕
                pic.SizeMode = PictureBoxSizeMode.StretchImage;
                pic.BorderStyle = BorderStyle.None;
                pic.Height = pic.Width = 16;//图片大小固定为16
                pic.Left = -40;  //隐藏图片
                txt.Width = Width - 9;
                txt.Location = new Point(3, 6);
    
                txt.MouseEnter += new EventHandler(TextBoxEx2_MouseEnter);
                txt.MouseLeave += new EventHandler(TextBoxEx2_MouseLeave);
                pic.MouseEnter += new EventHandler(TextBoxEx2_MouseEnter);
                pic.MouseLeave += new EventHandler(TextBoxEx2_MouseLeave);
                txt.LostFocus += new EventHandler(Txt_LostFocus);
                txt.GotFocus += new EventHandler(Txt_GotFocus);
                pic.BackColor = Color.White;  //不设置成白色则边框会一同加阴影
            }
    
            #endregion
    
            #region - 事件 -
    
            private void TextBoxEx_Load(object sender, EventArgs e)
            {
                SetWaterMark();
            }
    
            private void TextBoxEx2_MouseEnter(object sender, EventArgs e)
            {
                _isFouse = true;
                this.Invalidate();
            }
    
            private void TextBoxEx2_MouseLeave(object sender, EventArgs e)
            {
                _isFouse = false;
                this.Invalidate();
            }
    
            private void Txt_GotFocus(object sender, EventArgs e)
            {
                if (txt.Text == @" " + WaterMark)
                {
                    //获得焦点,切换正常文字等待填写
                    txt.ForeColor = ForeColor;
                    txt.Text = " ";
                }
            }
    
            private void Txt_LostFocus(object sender, EventArgs e)
            {
                SetWaterMark();
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                Graphics g = e.Graphics;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;
    
                CalculateSizeAndPosition();
                Draw(e.ClipRectangle, e.Graphics);
               
    
                base.OnPaint(e);
            }
    
            #endregion
    
            #region - 帮助方法 -
    
            private void SetWaterMark()
            {
                if (_waterMark != null && (txt.Text == " " || txt.Text == @" " + WaterMark))  //用户没有输入
                {    
                    txt.ForeColor = _waterMarkColor;
                    txt.Text = @" " + WaterMark;
                }
                else
                {
                    txt.ForeColor = ForeColor;
                }
            }
    
            private void CalculateSizeAndPosition()
            {
                if (ForeImage != null)
                {
                    pic.Top = pic.Left = 3;
                    txt.Width = Width - pic.Width - 12;
                    txt.Location = new Point(16 + 3 + 3, 6);
                }
                else
                {
                    pic.Left = -40;  //隐藏图片
                    txt.Width = Width - 9;
                    txt.Location = new Point(3, 6);
                }
    
                //单行
                if (!txt.Multiline)
                {
                    Height = txt.Height + 9;
                }
                else
                {
                    txt.Height = Height - 9;
                }
            }
    
            private void Draw(Rectangle rectangle, Graphics g)
            {
    
                #region 画背景
                using (SolidBrush backgroundBrush = new SolidBrush(Color.White))
                {
                    g.FillRectangle(backgroundBrush, 2, 2, this.Width - 5, this.Height -4);
                }
                #endregion
    
                #region 画阴影(外边框)
    
                Color drawShadowColor = _shadowColor;
                if (!_isFouse)    //判断是否获得焦点
                {
                    drawShadowColor = Color.Transparent;
                }
                using (Pen shadowPen = new Pen(drawShadowColor))
                {
                    if (_radius == 0)
                    {
                        g.DrawRectangle(shadowPen, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1));
                    }
                    else
                    {
                        g.DrawPath(shadowPen, DrawHelper.DrawRoundRect(rectangle.X, rectangle.Y, rectangle.Width - 2, rectangle.Height - 1, _radius));
                    }
                }
                #endregion
    
                #region 画边框
                using (Pen borderPen = new Pen(_borderColor))
                {
                    if (_radius == 0)
                    {
                        g.DrawRectangle(borderPen, new Rectangle(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 3));
                    }
                    else
                    {
                        g.DrawPath(borderPen, DrawHelper.DrawRoundRect(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 2, _radius));
                    }
                }
                #endregion
            }
    
            #endregion
        }
    }
  • 相关阅读:
    关于relative和absolute的总结
    docker命令
    了解docker
    数据库性能监测指标(如Oracle、SqlServer)、LoadRunner 性能测试指标
    MySQL游标
    MySQL创建用户
    MySQL数据的操作
    MySQL创建数据库和表
    MySQL视图的操作
    MySQL数据备份与恢复
  • 原文地址:https://www.cnblogs.com/StupidsCat/p/3062711.html
Copyright © 2011-2022 走看看