专栏首页木宛城主ASP.NET MVC使用Bootstrap系列(3)——使用Bootstrap 组件

ASP.NET MVC使用Bootstrap系列(3)——使用Bootstrap 组件

Bootstrap为我们提供了十几种的可复用组件,包括字体图标、下拉菜单、导航、警告框、弹出框、输入框组等。在你的Web Application中使用这些组件,将为用户提供一致和简单易用的用户体验。

Bootstrap组件本质上是结合了各种现有Bootstrap元素以及添加了一些独特Class来实现。Bootstrap元素我在上一篇文章中涉及到,具体可以参考《ASP.NET MVC使用Bootstrap系列(2)——使用Bootstrap CSS和HTML元素》。

在这篇博客中,我将继续探索Bootstrap丰富的组件以及将它结合到ASP.NET MVC项目中。

Bootstrap 导航条

Bootstrap导航条作为"明星组件"之一,被使用在大多数基于Bootstrap Framework的网站上。为了更好的展示Bootstrap导航条,我在ASP.NET MVC的_Layout.cshtml布局页创建一个fixed-top导航条,当然它是响应式的——在小尺寸、低分辨率的设备上打开时,它将会只展示一个按钮并带有3个子菜单,当点击按钮时垂直展示他们。在网页上显示如下:

在移动设备上显示如下:

在ASP.NET MVC默认的_Layouts.cshtml布局页中已经帮我们实现了上述功能,打开它对其稍作修改,如下代码片段所示:

<div class="navbar navbar-inverse navbar-fixed-top">

    <div class="container">

        <div class="navbar-header">

            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">

            <span class="icon-bar"></span>

            <span class="icon-bar"></span>

            <span class="icon-bar"></span>

            </button>

            @Html.ActionLink("Northwind Traders", "Index", "Home", null, new { @class = "navbar-brand" })

        </div>

        <div class="navbar-collapse collapse">

            @Html.Partial("_BackendMenuPartial")

            @Html.Partial("_LoginPartial")

        </div>

    </div>

</div>

其中class为.navbar-fixed-top可以让导航条固定在顶部,还可包含一个 .container 或 .container-fluid 容器,从而让导航条居中,并在两侧添加内补(padding)

注意,我使用了2个局部视图(_BackendMenuPartial和LoginPartial)来生成余下的导航条(使用.navbar-collapse类在低分辨率设备中折叠),其中局部视图逻辑是基于当前访问的用户是否登陆来控制是否显示。

首先,添加如下代码在_BackendMenuPartial视图中,这将会在导航条中产生一个搜索框:

@using (Html.BeginForm("Index", "Search", FormMethod.Post, new { @class = "navbar-form navbar-left", role = "search" }))

{

    <div class="form-group">

        @Html.TextBox("searchquery", "", new { @id = "searchquery", @class = "form-control input-sm", placeholder = "Search" })

        @Html.Hidden("fromcontroller", @ViewContext.RouteData.Values["controller"], new { @id = "fromcontroller" })

    </div>

    <button type="submit" class="btn btn-default btn-xs">GO</button>

}

因为Bootstrap导航条作为整个网站的公共部分,要实现快速搜索那么必须要知道当前所处于哪个Controller,这样才能提高检索效率。所以上述代码中,增加了一个Id为fromcontroller隐藏字段,代表当前访问的Controller。

当点击搜索时,发送HTTP POST请求到Index Action下。然后根据传递过来的fromcontroller来swith到具体的Action来执行搜索,具体的搜索逻辑代码如下:

public ActionResult Index(string searchquery, string fromcontroller)

{

    switch (fromcontroller)

    {

        case "Products":

        return RedirectToAction("SearchProductsResult", new { query = searchquery });

         

        case "Customers":

        return RedirectToAction("SearchCustomersResult", new { query = searchquery });

         

        case "Employees":

        return RedirectToAction("SearchEmployeesResult", new { query = searchquery });

    }

    return View();

}

具体搜索的Action如下:

public ActionResult SearchProductsResult(string query)

{

    ViewBag.SearchQuery = query;

    var results = _context.Products.Where(p => p.ProductName.Contains(query)).ToList();

    return View(results);

}

 

public ActionResult SearchCustomersResult(string query)

{

    ViewBag.SearchQuery = query;

    var results = _context.Customers.Where(p => p.CompanyName.Contains(query)

    || p.ContactName.Contains(query)

    || p.City.Contains(query)

    || p.Country.Contains(query)).ToList();

    return View(results);

}

 

public ActionResult SearchEmployeesResult(string query)

{

    ViewBag.SearchQuery = query;

    var results = _context.Employees.Where(p => p.FirstName.Contains(query)

    || p.LastName.Contains(query)

    || p.Notes.Contains(query)).ToList();

    return View(results);

}

列表组

列表组是灵活又强大的组件,不仅能用于显示一组简单的元素,还能结合其他元素创建一组复杂的定制内容。上面的搜索为我们重定向到Result视图,在此视图中,它为我们显示了搜索结果,为了更好的展示结果,我们可以使用列表组来显示搜索到的产品,视图中的代码如下所示:

@model IEnumerable<Bootstrap.Data.Models.Products>

@{

    ViewBag.Title = "搜索产品";

}

<div class="container">

    <div class="page-header">

        <h1>产品结果 <small>搜索条件: "@ViewBag.SearchQuery"</small></h1>

    </div>

    <ul class="list-group">

        @foreach (var item in Model)

        {

        <a href="@Url.Action("Edit","Products", new { id=@item.ProductID})" class="list-group-item">@item.ProductName <span class="badge">@item.UnitsInStock</span></a>

        }

    </ul>

</div>

在上述代码中,为无序列表(<ul>)的class设置为list-group,并且每一个<li>的class为list-group-item,这是一个最简单的列表组。

徽章

徽章用来高亮条目,可以很醒目的显示新的或者未读的条目数量,为一个元素设置徽章仅仅只需要添加<span>元素并设置它的class为badge。所以,在上述代码的基础上稍作修改,添加徽章,表示库存个数,如下HTML所示:

<a href="@Url.Action("Edit","Products", new { id=@item.ProductID})" class="list-group-item">
    @item.ProductName <span class="badge">@item.UnitsInStock</span>
</a>

显示的结果为如下截图:

媒体对象

媒体对象组件被用来构建垂直风格的列表比如博客的回复或者推特。在Northwind数据库中包含一个字段ReportTo表示Employee向另一个Employee Report。使用媒体对象可以直观来表示这种关系。在视图中的代码如下所示:

<div class="container">

<div class="page-header">

    <h1>员工搜索结果: <small>搜索条件: "@ViewBag.SearchQuery"</small></h1>

</div>

@foreach (var item in Model)

{

    <div class="media">

        <a class="pull-left" href="@Url.Action("Edit", "Employees", new { id = @item.EmployeeID })">

            <img class="media-object" src="@Url.Content("~/Images/employees/" + @item.EmployeeID + ".png")" alt="@item.FirstName" width="64" height="64">

        </a>

        <div class="media-body">

            <h4 class="media-heading">@item.FirstName @item.LastName</h4>

            @item.Notes

            @foreach (var emp in @item.ReportingEmployees)

            {

                <div class="media">

                    <a href="#" class="pull-left">

                        <img alt="@emp.FirstName" src="@Url.Content("~/Images/employees/" + @emp.EmployeeID + ".png")" class="media-object" width="64" height="64">

                    </a>

                    <div class="media-body">

                        <h4 class="media-heading">@emp.FirstName @emp.LastName</h4>

                        @emp.Title

                    </div>

                </div>

            }

        </div>

    </div>

 

}

</div>

显示结果如下:

可以看到,媒体对象组件是由一系列class为media、media-heading、media-body、media-object的元素组合而成,其中media-object用来表示诸如图片、视频、声音等媒体对象。

注:.pull-left 和 .pull-right 这两个类以前也曾经被用在了媒体组件上,但是,从 v3.3.0 版本开始,他们就不再被建议使用了。.media-left 和 .media-right 替代了他们,不同之处是,在 html 结构中, .media-right 应当放在 .media-body 的后面。

页头

当用户访问网页时,Bootstrap页头可以为用户提供清晰的指示。Bootstrap页头本质上是一个<h1>元素被封装在class为page-header的<div>元素中。当然你也可以利用<small>元素来提供额外的关于页面的信息,同时Bootstrap为页头添加了水平分隔线用于分隔页面,如下HTML即为我们构建了页头:

<div class="page-header">

    <h1>员工搜索结果: <small>搜索条件: "@ViewBag.SearchQuery"</small></h1>

</div>

路径导航

路径导航(面包屑)在Web 设计中被用来表示用户在带有层次的导航结构中当前页面的位置。类似于Windows资源管理器。如下HTML所示:

<ol class="breadcrumb">

    <li>@Html.ActionLink("Home", "Index", "Home")</li>

    <li>@Html.ActionLink("Manage", "Index", "Manage")</li>

    <li class="active">Products</li>

</ol>

在上面HTML代码中,通过指定有序列表(<ol>)的class为breadcrumb,每一个子路径用<li>来表示,其中通过设置<li>的class为active代表当前所处的位置。

各路径间的分隔符已经自动通过 CSS 的 :before 和 content 属性添加了。

分页

分页用来分隔列表内容,特别是显示大量数据时通过分页可以有效的减少服务器压力和提高用户体验,如下截图使用分页来显示产品列表:

要完成上述的分页,需要安装PagedList.Mvc程序包,在NuGet控制台中安装即可:Install-PackagePagedList.Mvc

然后修改Action,它需要接受当然的页码,它是一个可空的整数类型变量,然后设置PageSize等于5,表示每页显示5条记录,如下代码所示:

public ActionResult Index(int? page)

{

    var models = _context.Products.Project().To<ProductViewModel>().OrderBy(p => p.ProductName);

    int pageSize = 5;

    int pageNumber = (page ?? 1);

    return View(models.ToPagedList(pageNumber, pageSize));

}

在View中,使用PagedList动态生成分页控件:

<div class="container">

    <div class="page-header">

        <h1>Products <small>Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount</small></h1>

    </div>

 

    <ol class="breadcrumb">

        <li>@Html.ActionLink("Home", "Index", "Home")</li>

        <li>@Html.ActionLink("Manage", "Index", "Manage")</li>

        <li class="active">Products</li>

    </ol>

    <table class="table table-striped table table-hover">

        <thead>

        <tr>

            <th>

            Product Name

            </th>

            <th>

            Unit Price

            </th>

            <th>

            Units In Stock

            </th>

            <th>

            Discontinued

            </th>

            <th></th>

        </tr>

        </thead>

    <tbody>

    @foreach (var item in Model)

    {

    <tr class="@item.Status">

        <td>

            @Html.ActionLink(item.ProductName, "Edit", new { id = item.ProductID })

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.UnitPrice)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.UnitsInStock)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.Discontinued)

        </td>

        <td>

            @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })

        </td>

    </tr>

    }

    </tbody>

    </table>

    @Html.PagedListPager(Model, page => Url.Action("Index", new { page }), PagedListRenderOptions.ClassicPlusFirstAndLast)

    <p>

        <a href="@Url.Action("Create","Products")" class="btn btn-sm btn-primary" role="button">Create New</a>

    </p>

</div>

输入框组

输入框组为用户在表单输入数据时可以提供更多的额外信息。Bootstrap的输入框组为我们在Input元素的前面或者后面添加指定class的块,这些块可以是文字或者字体图标,如下所示:

<div class="form-group">

    <div class="col-sm-2 input-group">

        <span class="input-group-addon">

            <span class="glyphicon glyphicon-phone-alt"></span>

        </span>

        @Html.TextBox("txtPhone","1194679215",new { @class = "form-control" })

    </div>

</div>

上面的输入框组合中,在Textbox的左边放置了一个带有字体图标Phone的灰色块,结果如下所示:

不仅可以使用字体图标,还可以使用纯文本来显示信息,如下所示在Textbox右边放置了固定的邮箱域名:

<div class="form-group">

    <div class="col-sm-4 input-group">

        @Html.TextBox("txtEmail","1194679215", new { @class = "form-control" })

        <span class="input-group-addon">@@qq.com</span>

    </div>

</div>

当然也可以在Input元素的两边同时加上块,如下代码所示:

<div class="form-group">

    <div class="col-sm-2 input-group">

        <span class="input-group-addon">¥</span>

            @Html.TextBox("txtMoney","100",new { @class = "form-control" })

        <span class="input-group-addon">.00</span>

    </div>

</div>

按钮式下拉菜单

按钮式下拉菜单顾名思义,一个按钮可以执行多种action,比如既可以Save,也可以Save之后再打开一个新的Form继续添加记录,如下所示:

<div class="form-group">

    <div class="col-sm-offset-2 col-sm-10">

        <div class="btn-group">

            <button type="submit" class="btn btn-primary btn-sm">Save</button>

            <button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown">

                <span class="caret"></span>

                <span class="sr-only">Toggle Dropdown</span>

            </button>

            <ul class="dropdown-menu" role="menu">

                <li><a href="#" id="savenew">Save & New</a></li>

                <li class="divider"></li>

                <li><a href="#" id="duplicate">Duplicate</a></li>

            </ul>

        </div>

    </div>

</div>

警告框

Bootstrap警告组件通常被用作给用户提供可视化的反馈,比如当用户Save成功后显示确认信息、错误时显示警告信息、以及其他的提示信息。

Bootstrap提供了4中不同风格的警告,如下所示:

<div class="container">

    <div class="page-header">

        <h1>Alerts </h1>

    </div>


    <ol class="breadcrumb">

        <li>@Html.ActionLink("Home", "Index", "Home")</li>

        <li>Bootstrap</li>

        <li class="active">Alerts</li>

    </ol>


    <div class="alert alert-success"><strong>Success. </strong></div>

    <div class="alert alert-info"><strong>Info.</strong></div>

    <div class="alert alert-warning"><strong>Warning!</strong></div>

    <div class="alert alert-danger"><strong>Danger!</strong></div>


</div>

可关闭的警告框可以让用户点击右上角的X来关闭,你可以使用alter-dismissible 类:

<div class="alert alert-warning alert-Dismissible" role="alert">

    <button type="button" class="close" data-dismiss="alert">

        <span aria-hidden="true">&times;</span><span class="sr-only">Close</span>

    </button>

    <strong>Alert!</strong>这是可关闭的Alter

</div>

进度条

进度条在传统的桌面应用程序比较常见,当然也可以用在Web上。通过这些简单、灵活的进度条,可以为当前工作流程或动作提供实时反馈。Bootstrap为我们提供了许多样式的进度条。

  • 基本进度条

基本进度条是一种纯蓝色的进度条,添加一个class 为sr-only 的<span>元素在进度条中是比较好的实践,这样能让屏幕更好的读取进度条的百分比。

<div class="row">

<    h4>基本进度条</h4>

    <div class="progress">

        <div class="progress-bar" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%;">

            <span class="sr-only">80%完成</span>

        </div>

    </div>

</div>
  • 上下文情景变化进度条

上下文情景变化进度条组件使用与按钮和警告框相同的类,根据不同情境展现相应的效果。

  • progress-bar-success
  • progress-bar-info
  • progress-bar-warning
  • progress-bar-danger
  • 条纹动画效果进度条

为了让进度条更加生动,可以为其添加条纹效果,在进度条<div>中添加class为progress-striped。当然让进度条看起来有动画,可以再为其指定active的class在<div>上,如下所示:

<div class="progress progress-striped active">

    <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%">

        <span class="sr-only">40% 完成 (success)</span>

    </div>

</div>
  • 使用SignalR动态更新进度条

SignalR是ASP.NET的库,可以用来双向实时通信,在ASP.NET MVC项目中使用SignalR:1.首先通过NuGet来安装SignalR Nuget Package:

Install-Package Microsoft.AspNet.SignalR

2.在项目里新建一个名为Hubs的文件夹,并添加ProgressbarHub类,如下代码所示:

public class ProgressbarHub : Hub

{

    public void SendProgress()

    {

        for (int i = 0; i <= 100; i++)

        {

            Thread.Sleep(50);

            Clients.Caller.sendMessage(i + "%");

        }

    }

}

SendProgress方法很简单,向客户端发送消息(通过自增变量输出0—100)

3.在布局页添加对SignalR虚拟路径的引用:

<script src="~/signalr/hubs"></script>

4.在打包文件中,包含 SignalR.js

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(

"~/Scripts/jquery-{version}.js",

"~/Scripts/jquery.signalR-2.2.0"

));

5.在客户端建立与服务端的双向通信:

@section scripts

{

<script type="text/javascript" language="javascript">

 

    $(document).ready(function () {

    //$(".progress-bar").width('0%');

    });

 

    $("#start").click(function () {

        $(".progress-bar").width('0%');

        var progressNotifier = $.connection.progressbarHub;

        progressNotifier.client.sendMessage = function (message) {

            updateProgress(message);

        };


        $.connection.hub.start().done(function () {

            progressNotifier.server.sendProgress();

        });

    });

     

    function updateProgress(message) {

        $(".progress-bar").width(message);

        $("#progressbarTitle").html(message + ' Complete');

    }

</script>

}

你可以看到,上述代码先初始化和服务端的连接,然后设置被服务端调用的客户端方法updateProgress。

最后,我们建立了和服务端的连接并且启动了服务端的操作,你可以看到,我们调用了sendProgress方法——这已经在ProgressbarHub类中定义好了。这样当点击ID为start的按钮时动态为进度条更新了0-100的数值。

小结

在这篇博客中,探索了Bootstrap中丰富的组件,并将它结合到ASP.NET MVC项目中。通过实例可以发现,这类组件本质上是结合了各种现有Bootstrap元素以及添加了一些独特Class来实现。 更多的Bootstrap组件请参见:http://v3.bootcss.com/components/ 源代码下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ASP.NET MVC使用Bootstrap系列(2)——使用Bootstrap CSS和HTML元素

    Bootstrap提供了一套丰富CSS设置、HTML元素以及高级的栅格系统来帮助开发人员快速布局网页。所有的CSS样式和HTML元素与移动设备优先的流式栅格系统...

    用户1161731
  • ASP.NET MVC使用Bootstrap系列(4)——使用JavaScript插件

    序言 Bootstrap的JavaScript插件是以JQuery为基础,提供了全新的功能并且还可以扩展现有的Bootstrap组件。通过添加data att...

    用户1161731
  • 小谈网关项目中的设计模式

    在网关项目中,单例模式是出现频率最高的模式。同时,所有的单例对象被 IoC 框架 Guice 统一管理。

    用户1161731
  • Bootstrap Metronic 学习记录(二)菜单栏

    1.简介 1)  .环境配置 2)  .提取页面 2).动态生成菜单(无限级别树) 2.系统环境配置 项目需要程序数据支撑,这里选择MVC5.0+EF6.0[S...

    用户1149182
  • 分享个天气网7日天气样式

    最近项目里面用到了天气网“7日天气”的功能,本来想趴一个样式的,可是看了看太费劲,索性自己写吧,分享下。

    lzugis
  • 日期时间选择器、Bootstrap日期和时间表单组件。bootstrap-datetimepicker实现年月日,时分秒的选择。

    参考链接:http://www.bootcss.com/p/bootstrap-datetimepicker/

    别先生
  • 使用 Vue.js 和 Semantic-UI 做一个简单的愿望清单

    周末用 Vue.js 和 Semantic-UI 做了一个简单的愿望清单,记录以后想和喜欢的人一起做的事,疲惫的生活里总要有些温柔的梦想吧。

    叶庭云
  • Django+xadmin打造在线教育平台(七)

    代码 github下载 十、授课教师  10.1.讲师列表页 拷贝teacher-list.html和teacher-detail.html到template...

    zhang_derek
  • 使用 Cloudflare Worker 免费搭建网址导航网站

    GitHub:https://github.com/sleepwood/CF-Worker-Dir/ CloudFlare Worker:https://wor...

    Inkedus
  • 25、商品详情页

    (1)复制一份test.vue文件并重命名为goodsDetail作为我们的商品详情页面

    Ewall

扫码关注云+社区

领取腾讯云代金券