Discuz教程网

跟我学做c#皮肤美化--Textbox

[复制链接]
authicon 沧海逆天 发表于 2010-11-30 21:58:43 | 显示全部楼层 |阅读模式
效果预览

    还是先看看最终的效果图(和QQ登陆中的输入框效果差不多):




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

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

   具体实现:
先抛开水印不说。最重要的就是重写的OnPaint方法,如下:
  1. protected override void OnPaint(PaintEventArgs e)
  2.         {
  3.             Graphics g = e.Graphics;
  4.             g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  5.             g.SmoothingMode = SmoothingMode.HighQuality;

  6.             CalculateSizeAndPosition();
  7.             Draw(e.ClipRectangle, e.Graphics);

  8.             base.OnPaint(e);
  9.         }
复制代码
可以看出里面调用了两个方法,做过前面窗体换肤的可能对这个不陌生。就是绘画之前计算好所有的位置大小信息,然后再调用draw画出来。那么这次的calculateSizeAndPosition又做了什么呢?2点!1.判断是否有前端图片需要显示,2.判断是否处于multiline模式。代码如下:
  1. private void CalculateSizeAndPosition()
  2.         {
  3.             if (ForeImage != null)
  4.             {
  5.                 //图片大小固定为16
  6.                 pic.Height = pic.Width = 16;
  7.                 pic.Top = pic.Left = 3;
  8.                 txt.Width = Width - pic.Width - 12;
  9.                 txt.Location = new Point(16 + 3 + 3, 6);
  10.             }
  11.             else
  12.             {
  13.                 pic.Left = -40;  //隐藏图片
  14.                   txt.Width = Width - 9;
  15.                 txt.Location = new Point(3, 6);
  16.             }

  17.             //单行
  18.              if (!txt.Multiline)
  19.             {
  20.                 Height = txt.Height + 9;
  21.             }
  22.             else
  23.             {
  24.                 txt.Height = Height - 9;  //如果是多行则设置实际里面的输入文本框的高度
  25.             }
  26.         }
复制代码
在这个方法里面主要画了三个东西,大家看注释也知道了,分别是:背景,边框,辉光。要注意的就是这里面的微小距离要设置好,我也改了好几次才设置正确。在画边框和辉光的时候,因为实现了圆角边框所以要对圆角度进行判断。
现在绘画的方法也做好了,接下来就是出发重绘的事件了。不然它也不会自动帮你绘画啊^_^。显然当鼠标移上去和移出去的时候需要重新绘画。那我们就在下面几个方法中引发重绘事件:private void Draw(Rectangle rectangle, Graphics g)
  1. private void TextBoxEx2_MouseEnter(object sender, EventArgs e)
  2.         {
  3.             _isFouse = true;
  4.             this.Invalidate();
  5.         }

  6.         private void TextBoxEx2_MouseLeave(object sender, EventArgs e)
  7.         {
  8.             _isFouse = false;
  9.             this.Invalidate();
  10.         }
复制代码
代码很简单,不解释。
基本上面的做好了,大部分就完成了。下面我们完成水印的功能。至此,textbox美化讲解完毕,希望对你有帮助
实现水印效果

      水印我是这样子实现的:当用户离开输入焦点的时候检测当前用户有没有输入字符,如果没有输入则改变输入框的颜色(灰色),然后看起来就像是水印的感觉啦。我们专门写了一个函数来设置水印,如下:
  1.         private void SetWaterMark()
  2.         {
  3.             if (_waterMark != null && (txt.Text == " " || txt.Text == @" " + WaterMark))   //用户没有输入
  4.             {   
  5.                 txt.ForeColor = _waterMarkColor;
  6.                 txt.Text = @" " + WaterMark;
  7.             }
  8.             else
  9.             {
  10.                 txt.ForeColor = ForeColor;
  11.             }
  12.         }
复制代码
然后在什么地方调用呢?刚才上面也已经说了当用户离开焦点的时候判断,不过用户获得输入焦点的时候我们还要设置一下,如果当前的文本时水印的话就清空文本等待输入:
  1.         private void Txt_GotFocus(object sender, EventArgs e)
  2.         {
  3.             if (txt.Text == @" " + WaterMark)
  4.             {
  5.                 //获得焦点,切换正常文字等待填写
  6.                 txt.ForeColor = ForeColor;
  7.                 txt.Text = " ";
  8.             }
  9.         }

  10.         private void Txt_LostFocus(object sender, EventArgs e)
  11.         {
  12.             SetWaterMark();
  13.         }
复制代码
这里还有一点需要注意的是,在pageload里面我们也需要调用一下setwatermark方法,不然它一开始是不会显示滴!

源代码快照
  1. namespace QLFUI
  2. {
  3.     public partial class TextBoxEx : UserControl
  4.     {
  5.         #region - 变量 -

  6.         private Color _borderColor = Color.FromArgb(166, 208, 226);
  7.         private Color _shadowColor = Color.FromArgb(175, 212, 228);
  8.         private Image _foreImage = null;
  9.         private bool _isFouse = false;
  10.         private Color _backColor = Color.Transparent;
  11.         private string _waterMark = null;
  12.         private Color _waterMarkColor = Color.Silver;
  13.         private Color _foreColor = Color.Black;
  14.         private int _radius = 3;

  15.         #endregion

  16.         #region - 属性 -

  17.         [Category("QLFUI"), Description("边框颜色,BorderStyle为FixedSingle有效")]
  18.         public Color BorderColor
  19.         {
  20.             get { return _borderColor; }
  21.             set
  22.             {
  23.                 _borderColor = value;
  24.                 this.Invalidate();
  25.             }
  26.         }

  27.         [Category("QLFUI"), Description("边框阴影颜色,BorderStyle为FixedSingle有效")]
  28.         public Color ShadowColor
  29.         {
  30.             get { return _shadowColor; }
  31.             set
  32.             {
  33.                 _shadowColor = value;
  34.                 this.Invalidate();
  35.             }
  36.         }

  37.         [Category("QLFUI"), Description("显示的前端的图片")]
  38.         public Image ForeImage
  39.         {
  40.             get { return pic.Image; }
  41.             set
  42.             {
  43.                 _foreImage = value;
  44.                 pic.Image = _foreImage;
  45.                 Invalidate();
  46.             }
  47.         }

  48.         [Category("QLFUI"), Description("文字")]
  49.         public string Caption
  50.         {
  51.             get
  52.             {
  53.                 return txt.Text;
  54.             }
  55.             set
  56.             {
  57.                 txt.Text = value;
  58.                 SetWaterMark();
  59.                 Invalidate();
  60.             }
  61.         }

  62.         [Category("行为"), Description("是否多行显示")]
  63.         public bool Multiline
  64.         {
  65.             get { return txt.Multiline; }
  66.             set
  67.             {
  68.                 txt.Multiline = value;
  69.             }
  70.         }

  71.         [Category("行为"), Description("是否以密码形式显示字符")]
  72.         public bool UseSystemPasswordChar
  73.         {
  74.             get { return txt.UseSystemPasswordChar; }
  75.             set
  76.             {
  77.                 txt.UseSystemPasswordChar = value;
  78.             }
  79.         }

  80.         [Category("QLFUI"), Description("水印文字")]
  81.         public string WaterMark
  82.         {
  83.             get { return _waterMark; }
  84.             set
  85.             {
  86.                 _waterMark = value;
  87.                 Invalidate();
  88.             }
  89.         }

  90.         [Category("QLFUI"), Description("水印颜色")]
  91.         public Color WaterMarkColor
  92.         {
  93.             get { return _waterMarkColor; }
  94.             set
  95.             {
  96.                 _waterMarkColor = value;
  97.                 Invalidate();
  98.             }
  99.         }

  100.         #region 需要被隐藏的属性

  101.         [Browsable(false)]
  102.         public new BorderStyle BorderStyle
  103.         {
  104.             get { return BorderStyle.None; }
  105.         }

  106.         [Browsable(false)]
  107.         public new Color BackColor
  108.         {
  109.             get { return base.BackColor; }
  110.             set { base.BackColor = value; }
  111.         }

  112.         [Browsable(false)]
  113.         public new Image BackgroundImage
  114.         {
  115.             get { return null; }
  116.         }

  117.         [Browsable(false)]
  118.         public new ImageLayout BackgroundImageLayout
  119.         {
  120.             get { return base.BackgroundImageLayout; }
  121.             set { base.BackgroundImageLayout = value; }
  122.         }

  123.         #endregion

  124.         [Category("QLFUI"), Description("边角弯曲的角度(1-10),数值越大越弯曲")]
  125.         public int Radius
  126.         {
  127.             get { return _radius; }
  128.             set
  129.             {
  130.                 if (value > 10)
  131.                 {
  132.                     value = 10;
  133.                 }
  134.                 if (value < 0)
  135.                 {
  136.                     value = 0;
  137.                 }
  138.                 _radius = value;
  139.                 this.Invalidate();
  140.             }
  141.         }

  142.         [Browsable(true)]
  143.         [Category("外观"), Description("文本颜色")]
  144.         public new Color ForeColor
  145.         {
  146.             get { return _foreColor; }
  147.             set { _foreColor = value; }
  148.         }

  149.         [Browsable(true)]
  150.         [Category("外观"), Description("鼠标形状")]
  151.         public new Cursor Cursor
  152.         {
  153.             get { return txt.Cursor; }
  154.             set { txt.Cursor = value; }
  155.         }

  156.         [Category("行为"), Description("自动提示方式")]
  157.         public AutoCompleteMode AutoCompleteMode
  158.         {
  159.             get { return txt.AutoCompleteMode; }
  160.             set { txt.AutoCompleteMode = value; }
  161.         }

  162.         [Category("行为"), Description("自动提示类型")]
  163.         public AutoCompleteSource AutoCompleteSource
  164.         {
  165.             get { return txt.AutoCompleteSource; }
  166.             set { txt.AutoCompleteSource = value; }
  167.         }

  168.         #endregion

  169.         #region - 构造函数 -

  170.         public TextBoxEx()
  171.         {
  172.             SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
  173.             InitializeComponent();

  174.             BackColor = Color.Transparent;

  175.             //下面的图片和文本框的大小位置必须设置,否则首次启动时
  176.             //会出现莫名其妙的断痕
  177.             pic.SizeMode = PictureBoxSizeMode.StretchImage;
  178.             pic.BorderStyle = BorderStyle.None;
  179.             pic.Height = pic.Width = 16;//图片大小固定为16
  180.             pic.Left = -40;  //隐藏图片
  181.             txt.Width = Width - 9;
  182.             txt.Location = new Point(3, 6);

  183.             txt.MouseEnter += new EventHandler(TextBoxEx2_MouseEnter);
  184.             txt.MouseLeave += new EventHandler(TextBoxEx2_MouseLeave);
  185.             pic.MouseEnter += new EventHandler(TextBoxEx2_MouseEnter);
  186.             pic.MouseLeave += new EventHandler(TextBoxEx2_MouseLeave);
  187.             txt.LostFocus += new EventHandler(Txt_LostFocus);
  188.             txt.GotFocus += new EventHandler(Txt_GotFocus);
  189.             pic.BackColor = Color.White;  //不设置成白色则边框会一同加阴影
  190.         }

  191.         #endregion

  192.         #region - 事件 -

  193.         private void TextBoxEx_Load(object sender, EventArgs e)
  194.         {
  195.             SetWaterMark();
  196.         }

  197.         private void TextBoxEx2_MouseEnter(object sender, EventArgs e)
  198.         {
  199.             _isFouse = true;
  200.             this.Invalidate();
  201.         }

  202.         private void TextBoxEx2_MouseLeave(object sender, EventArgs e)
  203.         {
  204.             _isFouse = false;
  205.             this.Invalidate();
  206.         }

  207.         private void Txt_GotFocus(object sender, EventArgs e)
  208.         {
  209.             if (txt.Text == @" " + WaterMark)
  210.             {
  211.                 //获得焦点,切换正常文字等待填写
  212.                 txt.ForeColor = ForeColor;
  213.                 txt.Text = " ";
  214.             }
  215.         }

  216.         private void Txt_LostFocus(object sender, EventArgs e)
  217.         {
  218.             SetWaterMark();
  219.         }

  220.         protected override void OnPaint(PaintEventArgs e)
  221.         {
  222.             Graphics g = e.Graphics;
  223.             g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  224.             g.SmoothingMode = SmoothingMode.HighQuality;

  225.             CalculateSizeAndPosition();
  226.             Draw(e.ClipRectangle, e.Graphics);
  227.             

  228.             base.OnPaint(e);
  229.         }

  230.         #endregion

  231.         #region - 帮助方法 -

  232.         private void SetWaterMark()
  233.         {
  234.             if (_waterMark != null && (txt.Text == " " || txt.Text == @" " + WaterMark))   //用户没有输入
  235.             {   
  236.                 txt.ForeColor = _waterMarkColor;
  237.                 txt.Text = @" " + WaterMark;
  238.             }
  239.             else
  240.             {
  241.                 txt.ForeColor = ForeColor;
  242.             }
  243.         }

  244.         private void CalculateSizeAndPosition()
  245.         {
  246.             if (ForeImage != null)
  247.             {
  248.                 pic.Top = pic.Left = 3;
  249.                 txt.Width = Width - pic.Width - 12;
  250.                 txt.Location = new Point(16 + 3 + 3, 6);
  251.             }
  252.             else
  253.             {
  254.                 pic.Left = -40;  //隐藏图片
  255.                 txt.Width = Width - 9;
  256.                 txt.Location = new Point(3, 6);
  257.             }

  258.             //单行
  259.             if (!txt.Multiline)
  260.             {
  261.                 Height = txt.Height + 9;
  262.             }
  263.             else
  264.             {
  265.                 txt.Height = Height - 9;
  266.             }
  267.         }

  268.         private void Draw(Rectangle rectangle, Graphics g)
  269.         {

  270.             #region 画背景
  271.             using (SolidBrush backgroundBrush = new SolidBrush(Color.White))
  272.             {
  273.                 g.FillRectangle(backgroundBrush, 2, 2, this.Width - 5, this.Height -4);
  274.             }
  275.             #endregion

  276.             #region 画阴影(外边框)

  277.             Color drawShadowColor = _shadowColor;
  278.             if (!_isFouse)    //判断是否获得焦点
  279.             {
  280.                 drawShadowColor = Color.Transparent;
  281.             }
  282.             using (Pen shadowPen = new Pen(drawShadowColor))
  283.             {
  284.                 if (_radius == 0)
  285.                 {
  286.                     g.DrawRectangle(shadowPen, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width - 1, rectangle.Height - 1));
  287.                 }
  288.                 else
  289.                 {
  290.                     g.DrawPath(shadowPen, DrawHelper.DrawRoundRect(rectangle.X, rectangle.Y, rectangle.Width - 2, rectangle.Height - 1, _radius));
  291.                 }
  292.             }
  293.             #endregion

  294.             #region 画边框
  295.             using (Pen borderPen = new Pen(_borderColor))
  296.             {
  297.                 if (_radius == 0)
  298.                 {
  299.                     g.DrawRectangle(borderPen, new Rectangle(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 3));
  300.                 }
  301.                 else
  302.                 {
  303.                     g.DrawPath(borderPen, DrawHelper.DrawRoundRect(rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 3, rectangle.Height - 2, _radius));
  304.                 }
  305.             }
  306.             #endregion
  307.         }

  308.         #endregion
  309.     }
  310. }
复制代码
代码下载:
游客,如果您要查看本帖隐藏内容请回复





上一篇:混色器
下一篇:史上最牛的面试
authicon 夏夜星空浅唱 发表于 2012-5-2 15:07:53 | 显示全部楼层
look look look
authicon 封雪云天 发表于 2013-6-28 15:17:03 | 显示全部楼层
学习一下
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-2 06:57

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表