布局类似于APSX视图的母版页 用的是Razor的语法
创建布局
布局页面默认放在Shared目录 有几个自动生成的cshtml文件 删除它们 然后创建一个视图 命名为MyLayOut 取消勾选使用母版页或布局 打开该文件 删除以下代码
@{ Layout = null; }
我们将这个文件当做一个布局页面来使用 首先需要修改Views目录下的_ViewStart.cshtml 因为我们删掉了默认的布局页 所以在此视图中需要修改Layout的值 让其指向我们自定义的布局页
@{ Layout = "~/Views/Shared/MyLayOut.cshtml"; }
接着就可以使用以下方法来渲染子页面视图到布局页面中
RenderBody方法
渲染一个子视图 只要子视图是根据当前布局页创建的 则RenderBody指向的就是该视图 如
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>MyLayOut</title> </head> <body> <div style="background:#ff5252;width:400px;height:100px;font:12px 微软雅黑;padding:10px;color:white;"> <h1>布局页</h1> </html>
然后在控制器中创建一个ChildPage的Action方法
public ActionResult ChildPage() { return View(); }
为该Action创建一个视图 选择MyLayOut作为布局页
生成的ChildPage如下 在视图中创建一个div 输入文本ChildPage
@{ ViewBag.Title = "ChildPage"; Layout = "~/Views/Shared/MyLayOut.cshtml"; } <lable>ChildPage</lable>
运行一下 请求default/childpage 结果如图
RenderPage方法
此方法是将一个固定的视图页面渲染到布局页中 可以在布局中多次使用 而RenderBody指向的是一个动态的视图 只能在布局中使用一次 只要A视图是引用布局页创建的 那么访问A视图 就会先加载布局页 布局页的RenderBody指的就是A视图 如果B视图也引用了布局页 那么访问B视图 也会先加载布局页 布局页RenderBody指的就是B视图
比如我们可以将菜单这种固定的视图渲染到布局中 首先我们修改一下布局页
<html> <head> <meta name="viewport" content="width=device-width" /> <title>MyLayOut</title> </head> <body> <div style="background:#ff5252;width:600px;height:250px;font:12px 微软雅黑;padding:10px;color:white;"> <h1>布局页</h1> <div> <div style="float:left;">@RenderPage("~/Views/Default/Menu.cshtml")</div> <div style="float:left;margin-left:30px;background:black; width:200px;">@RenderBody()</div> </div> </div> </body> </html>
现在还没有Menu视图 创建一个Action方法Menu 为其添加视图 选择分布视图 取消勾选使用母版页或布局
.uls1{ margin:0; padding:0; list-style:none; } .links1{ color:white; font:13px Arial; display:block; border-left:12px solid #87bbbc; border-right:1px solid #87bbbc; padding-right:2px; text-decoration:none; } .lis1{ border-bottom:1px solid #b0eeef; } .links1:hover{ background:#8fc9b8; border-left:12px solid white; } .deadenlink{ background:#87bcac; border-left:12px solid black; color:white; font:13px Arial; display:block; border-left:12px solid black; border-right:1px solid #87bbbc; padding-right:2px; text-decoration:none; } .deadenlink:hover{ background:#b0d5ef; border-left:12px solid #e60b39; } </style> <div class='navigationbox'> <ul class="uls1"> <li class="lis1"><a href='#' class="links1">Google</a></li> <li class="lis1"><a href='#' class="links1">Microsoft</a></li> <li class="lis1"><a href='#' class='deadenlink'>Netscape</a></li> <li class="lis1"><a href='#' class="links1">W3C</a></li> <li class="lis1"><a href='#' class="links1">线性代数</a></li> <li class="lis1"><a href='#' class='deadenlink'>斯诺克</a></li> <li class="lis1"><a href='#' class="links1">芝宝打火机</a></li> <li class="lis1"><a href='#' class="links1">吴哥窟</a></li> </ul> </div>
运行一下 请求default/childpage 结果如图 可以看到布局页加载了一个固定的视图Menu 和一个动态的ChildPage视图
RenderSection方法
该方法声明了一个占位符 它会渲染指定的视图的一个部分 此方法专门用于使用了布局的各个视图 可以设置视图中某一部分的数据要显示在布局页中的某个位置上 我们知道RenderBody在布局页面中只能使用一次 而无法很灵活的将视图的某一部分定位在布局页面的某个位置 RenderSection可以解决这个问题 该方法参数1指定的是一个占位符的名字 参数2指定的是内容是否是必须的 一般设为false即可 在布局中如下使用该方法
@RenderBody() <p>@RenderSection("part",false)</p>
在ChildPage视图中通过section 指定要使用的占位符名字
@{ ViewBag.Title = "ChildPage"; Layout = "~/Views/Shared/MyLayOut.cshtml"; } <lable>ChildPage</lable> @section part{ <lable>Copyright ©2013 Tom</lable> }
这样 section 中的内容<lable>Copyright ©2013 Tom</lable>将显示在布局页的p标签中