TextBoxFor控件的扩展---Bootstrap在mvc上的应用

TextBoxFor控件的问题:

1:自带了样式,再用bootstrap样式会有冲突。

2:要加水印,js事件,限制输入长度比较麻烦。

因此需要对textboxfor控件进行扩展。

目标:

1:能使用bootstrap样式。

2:能复用mvc的验证。

3:可以方便的添加水印。

4:能限制输入字符的长度。

5:采用一些命名约定,使用扩展控件。(说白了,就是日期类型的直接给上边加上调用日期控件的调用。)

解决方案

最容易想到的解决办法就是直接写个扩展方法,进行字符串拼接生成控件。使用的时候:@BootStrap.TextBoxFor(u=>u.Email)

最终生成:

 <input class="form-control" data-val="true" data-val-length="字段 邮箱 必须是最大长度为 50 的字符串。" data-val-length-max="50" data-val-regex="字段 邮箱 必须与正则表达式“.+”匹配。" data-val-regex-pattern=".+" data-val-required="邮箱 字段是必需的。" id="Email" maxlength="50" name="Email" type="text" value="[email protected]"></input>
                <span class="field-validation-valid help-block" data-valmsg-for="Email" data-valmsg-replace="true"></span>

实现时候,悲催了。发现很难直接获取属性的验证信息,难道要自己再写反射,读取特性。生成对应的验证信息。

另一条路,借助mvc的htmlhelper来完成了。

        public static MvcHtmlString BsTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression,string css="", string placeholder="")
        {
            TagBuilder tagBuilder = new TagBuilder("input");
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
            //tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(ExpressionHelper.GetExpressionText(expression), metadata));
            string name = ExpressionHelper.GetExpressionText(expression);
            //var vas = htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata);
            htmlHelper.ValidateFor(expression);
            tagBuilder.MergeAttribute("name",name);
            tagBuilder.GenerateId(name);
            tagBuilder.MergeAttribute("type","text");       //核心代码,直接通过这个方法可以获取属性上的验证信息,如:“data-val= ....”。有一点要注意,在一个属性上,调用了这个方法完成后。mvc底层代码会自动释放这个验证对象。也就是说,一个属性的输入文本框只会第一个上边会生成相关的验证。
var vas = htmlHelper.GetUnobtrusiveValidationAttributes(name,metadata); if (!string.IsNullOrEmpty(placeholder)) { tagBuilder.MergeAttribute("placeholder",placeholder); }       //string类型,看有没长度限制,如果有,增加maxlength,minlength
            if (metadata.ModelType == typeof (string))
            {
                var len = metadata.ContainerType.GetProperty(name).GetCustomAttribute(typeof(StringLengthAttribute));
                if (len != null)
                {
                    var stringlength = (StringLengthAttribute) len;
                    if (stringlength.MaximumLength > 0)
                    {
                        tagBuilder.MergeAttribute("maxlength", stringlength.MaximumLength.ToString());
                    }
                    if (stringlength.MinimumLength > 0)
                    {
                        tagBuilder.MergeAttribute("minlength", stringlength.MinimumLength.ToString());
                    }
                }
            }       //如果model值不为,null,进行赋值。
            if (metadata.Model != null)
            {          todo:还要完善。
                tagBuilder.MergeAttribute("value",metadata.Model.ToString());
            }
            tagBuilder.MergeAttributes(vas);
            tagBuilder.AddCssClass("form-control");
            if (!string.IsNullOrEmpty(css))
            {
                tagBuilder.AddCssClass(css);
            }       //约定,属性名以day或者date结束的属性为日体,为其增加日期选择功能。
            if (name.ToLower().EndsWith("day") || name.ToLower().EndsWith("date"))
            {
                tagBuilder.MergeAttribute("onclick", "WdatePicker()");
            }
            return new MvcHtmlString(tagBuilder.ToString());
        }

最终实现效果:

View部分代码:

  <div class="form-group">
            @Html.BsLabelFor(model => model.Email)
            <div class="col-xs-10">
                @*@Html.TextBoxFor(model => model.Email, new { @class = "form-control" })*@
                @Html.BsTextBoxFor(model=>model.Email)
                @Html.ValidationMessageFor(model => model.Email, "", new { @class = "help-block" })

            </div>
        </div>
        <div class="form-group">
            @Html.BsLabelFor(model => model.Salary)
            <div class="col-xs-2 input-group" >
                <div class="input-group-addon">$</div>
            @Html.BsTextBoxFor(model => model.Salary)
                <div class="input-group-addon">.00</div>
            </div><div class="col-xs-8">
                @Html.ValidationMessageFor(model => model.Salary, "", new { @class = "help-block" })
            </div>
        </div>
        <div class="form-group">
            @Html.BsLabelFor(model => model.Code)
            <div class="col-xs-2">
                @Html.BsTextBoxFor(model => model.Code)
            </div><div class="col-xs-8">
                @Html.ValidationMessageFor(model => model.Code, "", new { @class = "help-block" })
            </div>
        </div>
        <div class="form-group">
            @Html.BsLabelFor(model => model.BirthDay)
            <div class="col-xs-2 input-group">
                @Html.BsTextBoxFor(model => model.BirthDay)<div class="input-group-addon" onclick="WdatePicker({ el: ‘BirthDay‘ })">
                                                               <span class="glyphicon glyphicon-th"></span>
</div>
            </div><div class="col-xs-8">
                      @Html.ValidationMessageFor(model => model.BirthDay)
                  </div>
        </div>

viewModel代码:

  public class VerifyModel
    {
        public Guid Id { get; set; }
        [DisplayName("用户名")]
        [Required]
        [StringLength(15)]
        [Remote("CheckName", "Form")]
        public string UserName { get; set; }
        [DisplayName("密码")]
        [Required]
        [StringLength(20,MinimumLength = 4)]
        [DataType(DataType.Password)]
        public string PassWord { get; set; }
        [DataType(DataType.Password)]
        [System.ComponentModel.DataAnnotations.Compare("PassWord", ErrorMessage = "两次输入密码不一致")]
        [DisplayName("确认密码")]
        public virtual string ConfirmPassWord { get; set; }
        [StringLength(50)]
        [DisplayName("邮箱")]
        [Required]
        [DataType(DataType.EmailAddress)]
        [RegularExpression(@".+")]
        public string Email { get; set; }
        [RegularExpression(@"1\d{10}", ErrorMessage = "请输入正确的手机号码")]
        [DisplayName("手机")]
        [Required]
        public string Phone { get; set; }
        [DisplayName("薪水")]
        [Required]
        public decimal Salary { get; set; }
         [RegularExpression(@"d{6}", ErrorMessage = "邮编为六位数字")]
        [DisplayName("邮编")]
        [Required]
        public string Code { get; set; }
        [DisplayName("生日")]
        [Required]
        public DateTime BirthDay { get; set; }
    }

最后:

配合T4模板,采用一些命名约定能更快捷的生成各种表单页面。

时间: 2024-08-29 23:51:01

TextBoxFor控件的扩展---Bootstrap在mvc上的应用的相关文章

WPF中查找控件的扩展类

在wpf中查找控件要用到VisualTreeHelper类,但这个类并没有按照名字查找控件的方法,于是搜索网络,整理出下面这个类,感觉用起来很是方便. 贴出来,供大家参考. /// <summary> /// WPF/Silverlight 查找控件扩展方法 /// </summary> public static class VisualHelperTreeExtension { /// <summary> /// 根据控件名称,查找父控件 /// elementNa

改变FileUpload文件上传控件的显示方式,确认后上传

一.Aspx页面: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FileUploadDemo.aspx.cs" Inherits="WebApplication1.FileUploadDemo" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu

Qt qml中listview 列表视图控件(下拉刷新、上拉分页、滚动轴)

Qt qml中listview 列表视图控件(下拉刷新.上拉分页.滚动轴) 来源 https://www.cnblogs.com/surfsky/p/4352898.html 设置ListView涉及到将contentsY,即视图的可见部分的顶部,设置y为委托的值.另一个更改是interactive将视图设置为false.这样可以防止视图移动.用户不能再滚动列表或更改当前Item. contentY为列表上拉后列表左上角点距显示框左上解点的高度listView1.height为可显示部分的高度,

WinForms中TreeView控件的扩展与使用

EXE文件方便大家测试   源码下载 TreeView控件非常的好用,在我的公文系统中,使用TreeView控件选择接收公文的人员,支持单选,可多选 现提取出来,方便大家使用 涉及到的知识点 1:从Xml文件中加载内容显示到TreeView控件中 <?xml version="1.0" encoding="utf-8"?> <根目录> <组 名称="校长" 用户ID="1000"> <

【C#】使用IExtenderProvider为控件添加扩展属性,像ToolTip那样

申明: - 本文适用于WinForm开发 - 文中的“控件”一词是广义上的说法,泛指包括ToolStripItem.MenuItem在内单个界面元素,并不特指继承自Control类的狭义控件 用过ToolTip这个组件的童鞋都知道这样一个现象:在VS中拖入一个ToolTip,然后点击窗体中的各种控件,在其属性窗格中就会多出一个叫ToolTip的属性出来,如图: 本文要说的就是如何像ToolTip这样,为控件“扩展”出一个属性来(之所以用引号,是因为并不是真的为控件增加了一个属性,而是在VS中看起

C# WinForm控件美化扩展系列之给TextBox加水印

在一些软件中,我们看到当一个输入控件(textbox)没有输入而且没有焦点的时候,会显示一些提示信息,网上有一些介绍用复合控件来实现,其实我们直接继承textbox控件也很容易实现. 下面就介绍怎样来实现这个控件. 第一步:我们建一个继承 textbox 的类,命名为watermaktextbox. 第二步:给这个类添加两个属性,一个是emptytexttip,就是当控件没有输入内容和没有焦点的时候显示的提示文本,也就是水印了:另一个是emptytexttipcolor,就是提示文本的颜色. 第

C# windows 桌面控件的扩展

今天一同事 需要一个Windows from下 GridView的嵌套的控件,于是就去找了以前自己写的一些form 控件,发现居然没有人下载.同时查找以前的下载包也比较费时,于是乎就搞一个文章. 运行效果如下:

使用Anthem.NET 1.5中的FileUpload控件实现Ajax方式的文件上传

Anthem.NET刚刚发布了其最新的1.5版本,其中很不错的一个新功能就是对文件上传功能的Ajax实现.本文将简要介绍一下该功能的使用方法. Anthem.NET的下载与安装 Anthem.NET可以在此下载:http://sourceforge.net/project/showfiles.php?group_id=151897&package_id=168043&release_id=493609 下载之后解压缩至硬盘中的某一目录中,编译项目得到Anthem.dll.然后将其拷贝到We

Webform之FileUpload(上传按钮控件)简单介绍及下载、上传文件时图片预览

1.FileUpload上传控件:(原文:http://www.cnblogs.com/hide0511/archive/2006/09/24/513201.html) FileUpload 控件显示一个文本框控件和一个浏览按钮,使用户可以选择客户端上的文件并将它上载到 Web 服务器.用户通过在控件的文本框中输入本地计算机上文件的完整路径(例如,C:\MyFiles\TestFile.txt)来指定要上载的文件.用户也可以通过单击“浏览”按钮,然后在“选择文件”对话框中定位文件来选择文件.