ASP.NET MVC使用Bootstrap系统(2)——使用Bootstrap CSS和HTML元素
Bootstrap提供了一套丰富CSS设置、HTML元素以及高级的栅格系统来帮助开发人员快速布局网页。所有的CSS样式和HTML元素与移动设备优先的流式栅格系统结合,能让开发人员快速轻松的构建直观的界面并且不用担心在较小的设备上响应的具体细节。
Bootstrap 栅格(Grid)系统
在移动互联网的今天,越来越多的网站被手机设备访问,移动流量在近几年猛增。Bootstrap 提供了一套响应式、移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列。
栅格参数
Bootstrap 3提供了一系列的预定义class来指定列的尺寸,如下所示:
Bootstrap 栅格系统被分割为12列,当布局你的网页时,记住所有列的总和应该是12。为了图示,请看如下HTML所示:
<div class="container"> <div class="row"> <div class="col-md-3" style="background-color: green;"> <h3>green</h3> </div> <div class="col-md-6" style="background-color: red;"> <h3>red</h3> </div> <div class="col-md-3" style="background-color: blue;"> <h3>blue</h3> </div> </div> </div>
注:Bootstrap 需要为页面内容和栅格系统包裹一个 .container 容器。
在上述代码中,我添加了一个class为container的div容器,并且包含了一个子的div元素row(行)。row div元素依次有3列。其中2列包含了col-md-3的class、一列包含了col-md-6的class。当他们组合在一起时,他们加起来总和是12.但这段HTML代码只作用于显示器分辨率>=992的设备。所以为了更好的响应低分辨率的设备,我们需要结合不同的CSS栅格class。故添加对平板、手机、低分辨率的PC的支持,需要加入如下class:
<div class="container"> <div class="row"> <div class="col-xs-3 col-sm-3 col-md-3" style="background-color: green;"> <h3>green</h3> </div> <div class="col-xs-6 col-sm-6 col-md-6" style="background-color: red;"> <h3>red</h3> </div> <div class="col-xs-3 col-sm-3 col-md-3" style="background-color: blue;"> <h3>blue</h3> </div> </div> </div>
Bootstrap HTML元素
Bootstrap已经为我们准备好了一大堆带有样式的HTML元素,如:
- Tables
- Buttons
- Forms
- Images
Bootstrap Tables(表格)
Bootstrap为HTML tables提供了默认的样式和自定义他们布局和行为的选项。为了更好的演示,我使用精典的Northwind示例数据库以及如下技术:
- 用ASP.NET MVC来作为Web应用应用程序
- Bootstrap前端框架
- Entity Framework来作为ORM框架
- StructureMap执行我们项目的依赖注入和控制反转,使用Nuget来安装
- AutoMapper自动映射Domain Model到View Model,使用Nuget来安装
打开Visual Studio,创建一个ASP.NET MVC的项目,默认情况下,VS已经为我们添加了Bootstrap的文件。为了查看效果,按照如下的步骤去实施:
- 在ASP.NET MVC项目中的Models文件下添加一个ProductViewModel
public class ProductViewModel { public int ProductId { get; set; } public string ProductName { get; set; } public decimal? UnitPrice { get; set; } public int? UnitsInStock { get; set; } public bool Discontinued { get; set; } public string Status { get; set; } }
- 在APP_Data文件夹中添加AutoMapperConfig类,通过AutoMapper,为ProductViewModel的Status属性创建了一个条件映射,如果Product是discontinued,那么Status为danger;如果UnitPrice大于50,则设置Status属性为info;如果UnitInStock小于20,那么设置Status为warning。代码的逻辑如下:
Mapper.CreateMap<Product, ProductViewModel>() .ForMember(dest => dest.Status, opt => opt.MapFrom (src => src.Discontinued ? "danger" : src.UnitPrice > 50 ? "info" : src.UnitsInStock < 20 ? "warning" : ""));
- 添加一个ProductController并且创建名为Index的Action
public class ProductController : Controller { // // GET: /Product/ private readonly ApplicationDbContext _context; public ProductController(ApplicationDbContext context) { this._context = context; } public ActionResult Index() { var products = _context.Products.Project().To<ProductViewModel>().ToArray(); return View(products); } }
- 上述代码使用依赖注入获取Entity Framework DbContext对象,Index Action接受从数据库中返回Products 集合然后使用AutoMapper映射到每一个ProductViewModel对象中,最后为View返回数据。
- 在视图上使用Bootstrap HTML table来显示数据
<div class="container"> <h3>Products</h3> <table class="table"> <thead> <tr> <th> Product Name </th> <th> Unit Price </th> <th> Units In Stock </th> <th> Discontinued </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.ProductName) </td> <td> @Html.DisplayFor(modelItem => item.UnitPrice) </td> <td> @Html.DisplayFor(modelItem => item.UnitsInStock) </td> <td> @Html.DisplayFor(modelItem => item.Discontinued) </td> </tr> } </tbody> </table> </div>
呈现的数据如下所示:
Bootstrap Tables 其余样式
Bootstrap提供了额外的样式来修饰table。比如使用table-bordered来显示边框,table-striped显示奇偶数行间颜色不同(斑马条纹状),table-hover顾名思义,当鼠标移动行时高亮,通过添加 .table-condensed 类可以让表格更加紧凑,单元格中的内补(padding)均会减半,修改后的代码如下所示:
<table class="table table-bordered table-striped table-hover"> </table>
显示的效果如下:
Bootstrap上下文Table 样式
Bootstrap提供了额外的class能让我们修饰<td>和<tr>的样式,提供的class如下:
- Active
- Success
- Info
- Warning
- Danger
修改上述代码,为<tr>动态添加样式:
@foreach (var item in Model) { <tr class="@item.Status"> <td> @Html.DisplayFor(modelItem => item.ProductName) </td> <td> @Html.DisplayFor(modelItem => item.UnitPrice) </td> <td> @Html.DisplayFor(modelItem => item.UnitsInStock) </td> <td> @Html.DisplayFor(modelItem => item.Discontinued) </td> </tr> }
更新过后的效果如下所示:
Bootstrap Buttons
Bootstrap提供了许多各种不同颜色和大小的buttons,为核心的buttons提供6种颜色和4种尺寸可以选择,同样通过设置class属性来显示不同的风格:
• btn btn-primary btn-xs
• btn btn-default btn-sm
• btn btn-default
• btn btn-sucess btn-lg
可以为Button设置颜色的class:
• btn-default
• btn-primary
• btn-success
• btn-info
• btn-warning
• btn-danger
所以可以使用如下代码来呈现效果:
<div class="row"> <!-- default按钮 --> <button type="button" class="btn btn-default btn-xs"> Default & Size=Mini </button> <button type="button" class="btn btn-default btn-sm"> Default & Size=Small </button> <button type="button" class="btn btn-default">Default</button> <button type="button" class="btn btn-default btn-lg"> Default & Size=Large </button> </div>
显示效果如下:
Bootstrap Form(表单)
表单常见于大多数业务应用程序里,因此统一的样式有助于提高用户体验,Bootstrap提供了许多不同的CSS样式来美化表单。
- 水平表单
使用ASP.NET MVC的HTML.BeginForm可以方便的创建一个表单,通过为<form>添加名为form-horizontal的class来创建一个Bootstrap 水平显示表单。
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { <div class="form-group"> @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.UserName) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Password) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Log in" class="btn btn-default" /> </div> </div> }
上述代码中,使用class为form-group的<div>元素包裹了2个Html方法(Html.LabelFor、Html.TextboxFor),这能让Bootstrap 验证样式应用在form 元素上,当然你也可以使用Bootstrap 栅格col-* class来指定form 中元素的宽度,效果如下显示:
- 垂直表单
Bootstrap基础表单默认情况下是垂直显示内容,在Html.BeginForm帮助方法里移除class为form-horizontal和class col-*后,显示的效果如下:
- 内联表单
内联表单表示所有的form 元素一个接着一个水平排列,只适用于视口(viewport)至少在 768px 宽度时(视口宽度再小的话就会使表单折叠)。
记得一定要添加 label 标签,如果你没有为每个输入控件设置 label 标签,屏幕阅读器将无法正确识别。对于这些内联表单,你可以通过为label 设置 .sr-only 类将其隐藏。详细代码如下:
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "form-inline", role = "form" })) { <div class="form-group"> @Html.LabelFor(m => m.UserName, new { @class = "sr-only" }) @Html.TextBoxFor(m => m.UserName, new { @class = "form-control", placeholder = "Enter your username" }) @Html.ValidationMessageFor(m => m.UserName) </div> <div class="form-group"> @Html.LabelFor(m => m.Password, new { @class = "sr-only" }) @Html.PasswordFor(m => m.Password, new { @class = "form-control", placeholder = "Enter your username" }) @Html.ValidationMessageFor(m => m.Password) </div> <div class="form-group"> <input type="submit" value="Log in" class="btn btn-default" /> </div> }
显示效果如下:
Bootstrap Image
在 Bootstrap 3.0中,通过为图片添加 .img-responsive 类可以让图片支持响应式布局。其实质是为图片设置了 max-width: 100%;、 height: auto; 和 display: block; 属性,从而让图片在其父元素中更好的缩放。
通过为 <img> 元素添加以下相应的类,可以让图片呈现不同的形状。
-
img-rounded
-
img-circle
-
img-thumbnail
请看如下代码:
<div class="row"> <h3>Our Team</h3> @foreach (var item in Model) { <div class="col-md-4"> <img src="@Url.Content("~/Images/employees/" + item.EmployeeID + ".png")" alt="@item.FirstName@item.LastName" class="img-circle img-responsive"> <h3> @item.FirstName @item.LastName <small>@item.Title</small> </h3> <p>@item.Notes</p> </div> } </div>
Bootstrap 验证样式
默认情况下ASP.NET MVC项目模板支持unobtrusive 验证并且会自动添加需要的JavaScript库到项目里。然而默认的验证不使用Bootstrap指定的CSS。当一个input元素验证失败,JQuery validation插件会为元素添加input-validation-error class(存在Site.css中)。那怎样不修改JQuery Validation插件而且使用Bootstrap内置的错误样式呢?
Bootstrap提供了class为has-error中的样式(label字体变为红色,input元素加上红色边框)来显示错误:
<div class="form-group has-error"> @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) </div> </div>
所以,我需要动态来为<div class=' from-group'>元素动态绑定/移除has-error。为了不修改JQuery.validation插件,我在Scripts文件夹中添加jquery.validate.bootstrap文件:
$.validator.setDefaults({ highlight: function (element) { $(element).closest('.form-group').addClass('has-error'); }, unhighlight: function (element) { $(element).closest('.form-group').removeClass('has-error'); }, });
这段脚本的通过调用setDefaults方法来修改默认的JQuery validation 插件设置。看以看到我使用highlight和unhighlight方法来动态添加/移除has-error class。
最后将它添加到打包文件中
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.validate.js", "~/Scripts/jquery.validate.unobtrusive.js", "~/Scripts/jquery.validate.bootstrap.js"));
注:默认情况下,ASP.NET MVC使用通配符*来将jquery.validate*文件打包到jqueryval文件中,如下所示:
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"));
但是jquery.validate.bootstrap.js必须在jquery validate 插件后加载,所以我们只能显式的指定文件顺序来打包,因为默认情况下打包加载文件的顺序是按通配符代表的字母顺序排列的。
ASP.NET MVC创建包含Bootstrap样式编辑模板
- 基元类型
编辑模板(Editor Template)指的是在ASP.NET MVC应用程序中,基于对象属性的数据类型通过Razor视图渲染后,自动产生表单Input元素。ASP.NET MVC包含了若干的编辑模板,当然我们也可以实现扩展。编辑模板类似于局部视图,不同的是,局部视图通过name来渲染,而编辑模板通过类型来渲染。
举个栗子,@Html.EditorFor(model => model.Property),如果Property类型为string,那么@Html.Editor 会创建一个Type=Text的Input元素;如果Property类型为Password,那么会创建一个Type=Password的Input元素。所以EditorFor helper是基于model 属性的数据类型来渲染生成HTML。
不过美中不足的是,默认产生的HTML如下所示:
可以看到class=”text-box single-line”,但先前提到过,Bootstrap Form元素class必须是 form-control。
所以,为了让Editor helper生成class为form-control的表单元素,我们需要创建一个自定义的编辑模板来重写旧的模板。你需要如下操作:
- 在Shared文件夹中创建名为EditorTemplates(注意要一样的名称)的文件夹
- 添加名为string.cshtml(注意要一样的名称)文件,并添加如下代码:
@model string @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = "form-control" })
在上述代码中,我们调用 @Html.TextBox方法,并且传递了一个空的字符串作为textbox的name。这将会让model的属性名作为生成的textbox的name,并且textbox显示的内容是model的值,最后追加了名为class的attribute,而且其值为”form-control”。
重新生成项目,发现新生成的input元素它的class已经改为”form-control“了。如下所示:
- 非基元类型
ASP.NET MVC能让开发者创建根据自定义DataType的编辑模板,比如自动生成多行文本框并且规定行数为3行,也是同样的操作:
- 添加MultilineText. Cshtml(注意名称相同)文件到EditorTemplates中
- 添加如下代码:
@model string @Html.TextArea("", ViewData.TemplateInfo.FormattedModelValue. ToString(), new { @class = "form-control", rows = 3 })
- 为了让我们的Model的属性在渲染时采用MultilineText.cshtml编辑模板,我们需要为属性指定DataType attribute为MultilineText:
[DataType(DataType.MultilineText)] public string Description { get; set; }
最终显示如下所示:
小结
这篇文章为大家介绍了Bootstrap的响应式布局(grid),并且简单介绍了Bootstrap中的HTML元素,包括Table、Button、Form、Image…。然后修改了JQuery validate插件默认的的设置,使其友好支持Bootstrap中的错误提示样式。最后探索了ASP.NET MVC中的编辑模板,能让产生的input元素自动包含form-control样式。
Bootstrap样式上更多的内容,参考Bootstrap官网全局CSS这一章节内容(http://v3.bootcss.com/css/),谢谢大家支持。