http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 17142|回复: 4

[C#皮肤] C#皮肤-TextBox 控件实现

[复制链接]
发表于 2012-12-20 11:49:41 | 显示全部楼层 |阅读模式
                          C#皮肤-TextBox 控件实现
导读部分
-------------------------------------------------------------------------------------------------------------
C#皮肤-实现原理系列文章导航
http://www.sufeinet.com/thread-2-1-1.html

大家都知道WinForm的文本框的边框颜色是不能修改的,在这里咱们就看一下怎么样使用Aip的方法来实现修改边框的效果。
不但可以修改文本框的,任何基本控件都行,包括Windows窗体在内。一会儿大家可以参考一个我的公共方法。

我们先来看看实现后的效果吧



正常显示时效果 textbox11.jpg

在得到焦点时的效果 textbox12.jpg

大可以应该可以看得出来有什么不同,第一个图上是增加一个边框,颜色很谈的一条线,在得到焦点时会改变文本框的背景色,当然在失去焦点时会还原过来
这些效果都是可以自己修改的,我给出来的只是一个样子,比较得到焦点时的颜色可以自己修改,正常显示时的边框都可以自己修改。

来看看实现方式吧



先来看看是怎么实现边框的吧第一步我们来新建一个TextBox组件类
textbox13.jpg
                                             
大家都知道WinForm的文本框的边框颜色是不能修改的,在这里咱们就看一下怎么样使用Aip的方法来实现修改边框的效果。
不但可以修改文本框的,任何基本控件都行,包括Windows窗体在内。一会儿大家可以参考一个我的公共方法。

我们先来看看实现后的效果吧



正常显示时效果        

在得到焦点时的效果

大可以应该可以看得出来有什么不同,第一个图上是增加一个边框,颜色很谈的一条线,在得到焦点时会改变文本框的背景色,当然在失去焦点时会还原过来
这些效果都是可以自己修改的,我给出来的只是一个样子,比较得到焦点时的颜色可以自己修改,正常显示时的边框都可以自己修改。

来看看实现方式吧



先来看看是怎么实现边框的吧第一步我们来新建一个TextBox组件类


然后我们来实现一个边框
我们先来设置一些东西看构造方法
[code=csharp]public CTextBox()
            : base()
        {
            //设置为单行边框
            this.BorderStyle = BorderStyle.FixedSingle;

            //强制将分配的样式应用到控件
            this.UpdateStyles();

            //得到默认颜色关储存
            objcolor = BackColor;
        }[/code]

我之所以这样设置是为了下一步修改边框,保存默认颜色我不说大家也知道是为了什么吧。当然是在失去焦点时还原本来的颜色啦。
我们一起来看一下调用的代码吧
[code=csharp]/// <summary>
        /// 重新设置边框
        /// </summary>
        /// <param name="m">当前的Windows消息</param>
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == 0xf || m.Msg == 0x133)
            {
                SkinHelp.ResetBorderColor(m, this, 1, SkinHelp.ControlBorderBackColor);
            }
        }[/code]

我们只要重写一个WndProc这个方法就OK了,其实这里很简单。调用 一个父类的方法,然后判断消息的正确性,然后调用下面一个方法就可以了,我们主要一起来看一下ResetBorderColor方法吧
先看看方法的签名吧
[code=csharp]/// <summary>
        /// 修改控件或窗体的边框,例如Textbox或是Form窗体
        /// </summary>
        /// <param name="m">消息</param>
        /// <param name="control">控件对象</param>
        /// <param name="Nwidth">边框像素</param>
        /// <param name="objcolor">边框颜色</param>
        internal static void ResetBorderColor(Message m, Control control, int Nwidth, Color objcolor)[/code]
我们先来画一条线,根据颜色和边框像素取得一条线,其实这就是我们要的边框。
[code=csharp]//根据颜色和边框像素取得一条线
            System.Drawing.Pen pen = pen = new Pen(objcolor, Nwidth);[/code]
与此同时我们还要得到当前控件的句柄参考如下代码
[code=csharp]
//得到当前的句柄
            IntPtr hDC = Win32.GetWindowDC(m.HWnd);
            if (hDC.ToInt32() == 0)
            {
                return;
            }[/code]
我们绘制的方式就是,先得到句柄和边框效果,然后根据当前的句柄重新绘制一个新的Textbox出来,然后返回给当前的对象就OK了,代码书写过程如下
[code=csharp]if (pen != null)
            {
                //绘制边框
                System.Drawing.Graphics g = Graphics.FromHdc(hDC);
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.DrawRectangle(pen, 0, 0, control.Width - Nwidth, control.Height - Nwidth);
                pen.Dispose();
            }[/code]
最后我们释放一下就可以了
[code=csharp]//释放
            Win32.ReleaseDC(m.HWnd, hDC);[/code]
这个方法的所有代码如下
[code=csharp]/// <summary>
        /// 修改控件或窗体的边框,例如Textbox或是Form窗体
        /// </summary>
        /// <param name="m">消息</param>
        /// <param name="control">控件对象</param>
        /// <param name="Nwidth">边框像素</param>
        /// <param name="objcolor">边框颜色</param>
        internal static void ResetBorderColor(Message m, Control control, int Nwidth, Color objcolor)
        {
            //根据颜色和边框像素取得一条线
            System.Drawing.Pen pen = pen = new Pen(objcolor, Nwidth);
            //得到当前的句柄
            IntPtr hDC = Win32.GetWindowDC(m.HWnd);
            if (hDC.ToInt32() == 0)
            {
                return;
            }

            if (pen != null)
            {
                //绘制边框
                System.Drawing.Graphics g = Graphics.FromHdc(hDC);
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.DrawRectangle(pen, 0, 0, control.Width - Nwidth, control.Height - Nwidth);
                pen.Dispose();
            }

            //释放
            Win32.ReleaseDC(m.HWnd, hDC);
        }[/code]

其实有了这个方法之后我们不但但是可以做文本框的边框,几乎所有的控件和窗体都可以使用这个通用的方法来实现。
有关于win32的类在我的皮肤类文件里都有大家可以直接下载使用
这样我们的第一步工作就完成了,下面我们来实现一下得到和失去焦点时的效果吧,由于这个比较简单和就不一步一步的说了,一起来看看代码吧
[code=csharp]/// <summary>
        /// 在得到焦点时修改文体框的背景色
        /// </summary>
        /// <param name="e"></param>
        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            BackColor = Color.MistyRose;
        }
        
        /// <summary>
        /// 在失去焦点时还原文本框的颜色
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            BackColor = objcolor;
        }[/code]
好了这样我们的控件就可以出炉了,我们生成一下
textbox14.jpg

我直接拉了几个大家其实不用运行就可以看到忆经有边框了。
这个方法正如我刚在所说的一样是通用的,如果你想做一个自己想要的窗体的话也可以这样来实现,直接传参数就行了,
但是不要忘记了把窗体的边框先删除了。就是设置为空。
下面是实现的所有代码
[code=csharp]using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace bxyztSkin.CControls
{
    public partial class CTextBox : System.Windows.Forms.TextBox
    {
        /// <summary>
        /// 类说明:CTextBox控件的实现用来代替系统的TextBox控件
        /// 编码日期:2011-03-03
        /// 编 码 人:  苏飞
        /// 联系方式:361983679  Email:sufei.1013@163.com  Blogs:sufei.cnblogs.com
        /// </summary>
        public CTextBox()
            : base()
        {
            //设置为单选边框
            this.BorderStyle = BorderStyle.FixedSingle;

            //强制将分配的样式应用到控件
            this.UpdateStyles();

            //得到默认颜色关储存
            objcolor = BackColor;
        }

        #region 自定变量
        Color objcolor;
        #endregion

        /// <summary>
        /// 重新设置边框
        /// </summary>
        /// <param name="m">当前的Windows消息</param>
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == 0xf || m.Msg == 0x133)
            {
                SkinHelp.ResetBorderColor(m, this, 1, SkinHelp.ControlBorderBackColor);
            }
        }

        /// <summary>
        /// 在得到焦点时修改文体框的背景色
        /// </summary>
        /// <param name="e"></param>
        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            BackColor = Color.MistyRose;
        }
      
        /// <summary>
        /// 在失去焦点时还原文本框的颜色
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            BackColor = objcolor;
        }
    }
}[/code]

本帖被以下淘专辑推荐:

  • · 皮肤|主题: 15, 订阅: 0


1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2013-2-20 23:15:45 | 显示全部楼层
这今天在研究自定义控件,谢谢飞大哥的帖子
发表于 2013-7-5 14:45:00 | 显示全部楼层
问一下,
ASP.NET 的TextBox用法是不是和WINFORM一样的呢?
 楼主| 发表于 2013-7-5 15:12:27 | 显示全部楼层
gangn 发表于 2013-7-5 14:45
问一下,
ASP.NET 的TextBox用法是不是和WINFORM一样的呢?

用户肯定是一样的,保是功能不相同
发表于 2015-6-8 18:07:11 | 显示全部楼层
强烈支持楼主ing……
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-11-22 17:53

© 2014-2021

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