摘要:

现在的web程序开发避免不了智能手机和平板电脑上的使用,如果你希望发布你的应用程序给更广大客户使用的话,你将要拥抱可移动web浏览器的世界。向移动设备用户发布一个好的使用体验是很困难的-比只是发布桌面内容要难得多。它需要认真的计划,设计以及大量的测试。甚至很容易被新的移动设备或平板电脑困住。

MVC框架确实有一些特征帮助移动开发。但是MVC框架是一个服务端框架,接收HTTP请求并发出HTTP响应。你在开发移动客户端的时候,会碰到很多的困难,而它对这些的作用却很受限。MVC框架使用不同的移动设备策略,可以帮助到不同层面。有三个基本的你可以使用的移动设备策略,下面将分别介绍它们。

什么都不做(尽量少地做)

看起来像一个奇怪的主意,但是一些移动设备是能够处理那些为桌面客户端开发的内容的。许多的移动设备-不得不承认当今最新的-有高屏幕分辨率,很大的内存,可以快速地呈现HTML以及运行JavaScript。

响应式设计

另一个策略是为适应支持它将显示的设备,而创建页面内容。被称为响应式设计。CSS标准有能力让你根据设备的性能改变应用在元素上的样式,它是一个经常被使用的根据屏幕尺寸改变内容的排版的技术。

响应式设计是使用CSS处理的东西,它不直接由MVC框架管理。这篇文章将介绍如何使用Bootstrap库里包含的响应式设计,来装饰SportsStore应用程序。

创建响应式设计的页面头部

修改_Layout.cshtml文件。

 <!DOCTYPE html>

 <html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
<link href="~/Content/ErrorStyles.css" rel="stylesheet" />
<title>@ViewBag.Title</title>
<style>
.navbar-right {
float: right !important;
margin-right: 15px;
margin-left: 15px;
}
</style>
</head>
<body>
<div class="navbar navbar-inverse" role="navigation">
<a class="navbar-brand" href="#">
<span class="hidden-xs">SPORTS STORE</span>
<div class="visible-xs">SPORTS</div>
<div class="visible-xs">STORE</div>
</a>
@Html.Action("Summary", "Cart")
</div>
<div class="row panel">
<div id="categories" class="col-xs-3">
@Html.Action("Menu", "Nav")
</div>
<div class="col-xs-8">
@RenderBody()
</div>
</div>
</body>
</html>

我将显示SPORTS STORE品牌的链接,改成了现在这个样子。

<a class="navbar-brand" href="#">SPORTS STORE</a>

BootStrap使用一种称为media查询的方式定义了一系列的样式,hidden-xx和visible-xx。xx可以使用xs、sm、md、lg代替,分别表示超小屏幕、小屏幕、中等屏幕和大屏幕。

.col-xs- 超小屏幕 手机 (<768px)
.col-sm- 小屏幕 平板 (≥768px)
.col-md- 中等屏幕 桌面显示器 (≥992px)
.col-lg- 大屏幕 大桌面显示器 (≥1200px)

这里使用的是hidden-xs和visible-xs。

hidden-xs:在超小屏幕上隐藏该元素。

visible-xs:在超小屏幕上显示该元素。

运行程序,在大屏幕尺寸上,页面内容没有变化。如果将浏览器缩小到小于768px,SPORTS STORE链接文字将变成两行。

创建响应式布局的购物车摘要

修改Summary.cshtml文件。

 @model SportsStore.Domain.Entities.Cart

 <div class="navbar-right hidden-xs">
@Html.ActionLink("My Cart", "Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }, new { @class = "btn btn-default navbar-btn" })
</div>
<div class="navbar-right visible-xs">
<a href=@Url.Action("Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }) class="btn btn-default navbar-btn">
<span class="glyphicon glyphicon-shopping-cart"></span>
</a>
</div>

<div class="navbar-text navbar-right">
<b class="hidden-xs">Your cart:</b>
@Model.CartLines.Sum(x => x.Quantity) item(s),
@Model.ComputeTotalValue().ToString("c")
</div>

首先,在不希望在手机屏幕上(<768px)显示的页面元素,添加hidden-xs样式。这样,这两个元素在手机屏幕上将不会显示。

<div class="navbar-right hidden-xs">
@Html.ActionLink("My Cart", "Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }, new { @class = "btn btn-default navbar-btn" })
</div> <b class="hidden-xs">Your cart:</b>

然后,为手机屏幕显示的导航到购物车明细超链接,定义自己的样式。

<div class="navbar-right visible-xs">
<a href=@Url.Action("Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }) class="btn btn-default navbar-btn">
<span class="glyphicon glyphicon-shopping-cart"></span>
</a>
</div>

这里直接写<a></a>元素。因为需要使用<span></span>元素定义超链接文字样式。

class="glyphicon glyphicon-shopping-cart"是定义在BootStrap里的文字样式,它将显示一个小的购物车图标。

运行程序,在大屏幕尺寸上,页面内容没有变化。如果将浏览器缩小到小于768px,购物车摘要将显示成下面截图那样的购物车图标。

创建响应式布局的产品列表

在超小屏幕上,左边的导航菜单占用宽度有点大。我希望在超小屏幕上隐藏左边的导航菜单,而是将导航菜单做成按钮组显示在页面头部。

继续修改_Layout.cshtml文件。

 <!DOCTYPE html>

 <html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
<link href="~/Content/ErrorStyles.css" rel="stylesheet" />
<title>@ViewBag.Title</title>
<style>
.navbar-right {
float: right !important;
margin-right: 15px;
margin-left: 15px;
}
</style>
</head>
<body>
<div class="navbar navbar-inverse" role="navigation">
<a class="navbar-brand" href="#">
<span class="hidden-xs">SPORTS STORE</span>
<div class="visible-xs">SPORTS</div>
<div class="visible-xs">STORE</div>
</a>
@Html.Action("Summary", "Cart")
</div>
<div class="visible-xs">
@Html.Action("Menu", "Nav", new { horizontalLayout = true })
</div>
<div class="row panel">
<div id="categories" class="col-sm-4 hidden-xs">
@Html.Action("Menu", "Nav")
</div>
<div class="col-sm-8 col-xs-12">
@RenderBody()
</div>
</div>
</body>
</html>
  • 首先,修改左边导航菜单所在的DIV元素样式,添加hidden-xs,指定它再超小屏幕上不显示。修改右边产品列表所在的DIV元素样式,添加col-xs-12,指定在超小屏幕,宽度上占全部12列显示。
  • 然后,重新修改在小屏幕以及以上屏幕上,这两个DIV所占的宽度。col-sm-4指定左边菜单导航栏占三列。col-sn-8指定右边产品列表占8列。
  • 最后,使用visible-xs重新定义在超小屏幕上的产品导航栏。它仍旧以DIV显示,但是他的位置在页面头部,所以讲他写到class="row"所在的DIV上面。
  • 向Html.Action方法传入第三个参数,它是一个动态类型对象,定义了一个自定义属性horizontalLayout。将修改Menu视图,在Menu视图上能够获得传入视图的动态类型对象的动态属性值,根据属性值显示不同样式的菜单。

修改Menu.cshtml文件,根据传入的动态属性值,显示不同的菜单样式

 @model IEnumerable<string>

 @{
var horizontalLayout = (bool)(ViewContext.RouteData.Values["horizontalLayout"] ?? false);
var wrapperClass = horizontalLayout ? "btn-group btn-group-justified btn-group-md" : null;
}

<div class=@wrapperClass >
@Html.RouteLink("Home", new { controller = "Product", action = "List" }, new { @class = horizontalLayout ? "btn btn-default btn-sm" : "btn btn-block btn-default btn-lg" })
@foreach (var link in Model)
{
@Html.RouteLink(link, new
{
controller = "Product",
action = "List",
category = link,
page = 1
}, new
{
@class = (horizontalLayout ? "btn btn-default btn-sm" : ("btn btn-block btn-default btn-lg")) + (link == ViewBag.SelectedCategory ? " btn-primary" : "")
})
}
</div>
  • 通过ViewContext对象,获得传入到视图的动态类型对象ViewContext.RoutData,再通过ViewContext.RoutData.Values这个Dictionary,获得动态类型对象的动态属性值。
  • wrapperClass定义了超小屏幕上的按钮组样式。如果是超小屏幕,则按新的样式显示。否则它的值为null,MVC系统将在页面上自动删除这个class属性(将只显示成<div>)。
  • 超小屏幕的按钮组样式定义:btn-group btn-group-justified btn-group-sm,定义它是一个按钮组,自动对齐方式以及按钮组每个按钮尺寸。
  • 因为超小屏幕上显示成按钮组,而不是每个按钮单独一行btn-block的按钮,所有需要重新修改每个按钮的样式。使用条件表达式 horizontal?: 重新定义分组按钮样式为:btn btn-default btn-sm。与中等屏幕上的按钮不同的地方是尺寸,以及删除了btn-block。

运行程序,在大屏幕尺寸上,页面内容没有变化。如果将浏览器缩小到小于768px,导航菜单将变成下面截图的页面这样。

 使用针对Mobile的视图

响应式设计向所有设备发布相同的内容,并使用CSS自己来决定内容怎样被呈现。这个过程不需要引入服务端部分的代码,前提是你想使用基本相同的主题对待所有不同的设备。另一个可选的方法是使用服务器端访问客户端浏览器的功能,向不同的浏览器发送不同的HTML。如果你计划发送和桌面客户端完全不同的应用程序页面,这样做很方便。

MVC框架支持一个名叫显示模式的ASP.NET框架功能,它让你根据发送请求的客户端,创建不同的视图。这篇文章不打算介绍它了,读者可以搜索更多的文章对它进行完整的介绍。

跟我学ASP.NET MVC之八:SportsStrore移动设备的更多相关文章

  1. 跟我学ASP.NET MVC之五:SportsStrore开始

    摘要: 这篇文章将介绍一个ASP.NET应用程序SportsStore的开发过程. 开始 创建解决方案 创建工程 在New ASP.NET Project - SportsStore窗口中,选择Emp ...

  2. 跟我学ASP.NET MVC之三:完整的ASP.NET MVC程序-PartyInvites

    摘要: 在这篇文章中,我将在一个例子中实际地展示MVC. 场景 假设一个朋友决定举办一个新年晚会,她邀请我创建一个用来邀请朋友参加晚会的WEB程序.她提出了四个注意的需求: 一个首页展示这个晚会 一个 ...

  3. 跟我学ASP.NET MVC之二:第一个ASP.NET MVC程序

    摘要: 本篇文章带你一步一步创建一个简单的ASP.NET MVC程序.  创建新ASP.NET MVC工程 点击“OK”按钮后,打开下面的窗口: 这里选择“Empty”模板以及“MVC”选项.这次不创 ...

  4. 跟我学ASP.NET MVC之一:开篇有益

    摘要: ASP.NET MVC是微软的Web开发框架,结合了模型-视图-控制器(MVC)架构的有效性和整洁性,敏捷开发最前沿的思想和技术,以及现存的ASP.NET平台最好的部分.它是传统ASP.NET ...

  5. [转]我要学ASP.NET MVC 3.0(十二): MVC 3.0 使用自定义的Html控件

    本文转自:http://www.cnblogs.com/lukun/archive/2011/08/05/2128693.html 概述   在ASP.NET MVC框架中已经封装了很多基于Html标 ...

  6. 跟我学ASP.NET MVC之十一:URL路由

    摘要: 在MVC框架之前,ASP.NET假定在请求的URLs和服务器硬盘文件之间有直接的关系.服务器的职责是接收浏览器请求,从相应的文件发送输出. 这种方法只能工作于Web表单,每一个ASPX页面既是 ...

  7. 跟我学ASP.NET MVC之六:SportsStrore添加产品目录导航

    摘要: 上一篇文章,我建立了SportsStore应用程序的核心架构.现在我将使用这个架构向这个应用程序添加功能,你将开始看到这个基础架构的作用.我将添加重要的面向客户的简单功能,在这个过程中,你将看 ...

  8. 跟我学ASP.NET MVC之十:SportsStrore安全

    摘要: 在之前的文章中,我给SportsStore应用程序添加了产品管理功能,这样一旦我发布了网站,任何人都可能修改产品信息,而这是你必须考虑的.他们只需要知道你的网站有这个功能,以及功能的访问路径是 ...

  9. 跟我学ASP.NET MVC之七:SportsStrore一个完整的购物车

    摘要: SportsStore应用程序进展很顺利,但是我不能销售产品直到设计了一个购物车.在这篇文章里,我就将创建一个购物车. 在目录下的每个产品旁边添加一个添加到购物车按钮.点击这个按钮将显示客户到 ...

随机推荐

  1. XMPP系列(四)---发送和接收文字消息,获取历史消息功能

    今天开始做到最主要的功能发送和接收消息.获取本地历史数据. 先上到目前为止的效果图:              首先是要在XMPPFramework.h中引入数据存储模块: //聊天记录模块的导入 # ...

  2. How tomcat works 读书笔记十二 StandardContext 下

    对重载的支持 tomcat里容器对重载功能的支持是依靠Load的(在目前就是WebLoader).当在绑定载入器的容器时 public void setContainer(Container cont ...

  3. 关于GPL329A中获取摄像头sensor id的问题

    首先我拿到了sensor_id应用程序的源码,我要在上面添加获取ov2685 的 sensor id的代码. 利用find . -name  get_sensor_id找到该代码编译之后生成的a.ou ...

  4. <<操作系统精髓与设计原理>>读书笔记(一) 并发性:互斥与同步(1)

    <<操作系统精髓与设计原理>>读书笔记(一) 并发性:互斥与同步 并发问题是所有问题的基础,也是操作系统设计的基础.并发包括很多设计问题,其中有进程间通信,资源共享与竞争,多个 ...

  5. JAVA学习总结-面向对象

    前言:java面向对象中的知识可以说是整个java基础最核心的部分,不知不觉已经学完快2个月了,是时候复习一波了,刚开始学习的时候被绕的很懵逼,这次总结完毕之后有了很多新的感悟,这就是所谓的每有会意, ...

  6. Android开发阅读文档资源

    Android Studio:工具:http://developer.android.com/intl/zh-cn/tools/studio/index.html培训教程:http://develop ...

  7. Java自学编程学习之路资源合集

    Java Web学习 STEP.1---Java基础最重要 工欲善其事,必先利其器.想要学好Java Web,或者说想要开始学Java Web,Java的基础是必不可少. 基本语法(★★★★★) 数组 ...

  8. 微信小程序UI组件、开发框架、实用库...

    UI组件 weui-wxss ★852 - 同微信原生视觉体验一致的基础样式库 Wa-UI ★122 - 针对微信小程序整合的一套UI库 wx-charts ★105 - 微信小程序图表工具 wema ...

  9. 利用Python脚本悄无声息的遥控室友电脑开机密码!

    整蛊一下室友就行了,切勿用于非法用途! 利用python脚本控制室友windows系统电脑的开机密码.利用random()生成随机数(密码),天知地知,密码只有你自己知道! Python代码分为cli ...

  10. 编程之美2.18 数组分割 原创解O(nlogn)的时间复杂度求解:

    题目:有一个无序.元素个数为2n的正整数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组的和最接近? 1 1 2 -> 1 1 vs  2 看题时,解法的时间复杂度一般都大 ...