为asp.net mvc创建可重用的ui组件

来源:互联网 发布:linux公社 ftp 编辑:程序博客网 时间:2024/05/22 02:12

网站可以看做是许多不同的窗口部件组成的,并且很多网站拥有类似的功能部件,比如博客的边条,如下:

image

html代码如下:

<div id="sidebar">    <div class="block">        <h3>            Simple Block</h3>        <div class="content">            <p>                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor                incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud                exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>        </div>    </div>    <div class="block notice">        <h4>            Notice Title</h4>        <p>            Morbi posuere urna vitae nunc. Curabitur ultrices, lorem ac aliquam blandit, lectus            eros hendrerit eros, at eleifend libero ipsum hendrerit urna. Suspendisse viverra.            Morbi ut magna. Praesent id ipsum. Sed feugiat ipsum ut felis. Fusce vitae nibh            sed risus commodo pulvinar. Duis ut dolor. Cras ac erat pulvinar tortor porta sodales.            Aenean tempor venenatis dolor.</p>    </div>    <div class="block">        <div class="sidebar-block">            <h4>                Sidebar Inner block Title</h4>            <p>                Morbi posuere urna vitae nunc. Curabitur ultrices, lorem ac <a href="#">aliquam blandit</a>                , lectus eros hendrerit eros, at eleifend libero ipsum hendrerit urna. Suspendisse                viverra. Morbi ut magna. Praesent id ipsum. Sed feugiat ipsum ut felis. Fusce vitae                nibh sed risus commodo pulvinar. Duis ut dolor. Cras ac erat pulvinar tortor porta                sodales. Aenean tempor venenatis dolor.            </p>        </div>    </div></div>

如果为其定义了单独的css,这部分代码配合样式表,其他地方copy一下就可使用,基本保持此块布局不变

在MVC中

经过研究 ASP.Net source code, 通过对helpI’ve based my extension on the @Html.BeginForm helper.这意味着上面的html标签可被如下方法替换:

@using MVCThemedApp1.Infrastructure<div id="sidebar">    @using (Html.SimpleBlock("Simple Block"))    {        <p>            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor            incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud            exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>    }    @using (Html.NoticeBlock("Notice Title"))    {        <p>            Morbi posuere urna vitae nunc. Curabitur ultrices, lorem ac aliquam blandit, lectus            eros hendrerit eros, at eleifend libero ipsum hendrerit urna. Suspendisse viverra.            Morbi ut magna. Praesent id ipsum. Sed feugiat ipsum ut felis. Fusce vitae nibh            sed risus commodo pulvinar. Duis ut dolor. Cras ac erat pulvinar tortor porta sodales.            Aenean tempor venenatis dolor.</p>    }    @using (Html.InnerBlock("Sidebar Inner block Title"))    {        <p>            Morbi posuere urna vitae nunc. Curabitur ultrices, lorem ac <a href="#">aliquam blandit</a>            , lectus eros hendrerit eros, at eleifend libero ipsum hendrerit urna. Suspendisse            viverra. Morbi ut magna. Praesent id ipsum. Sed feugiat ipsum ut felis. Fusce vitae            nibh sed risus commodo pulvinar. Duis ut dolor. Cras ac erat pulvinar tortor porta            sodales. Aenean tempor venenatis dolor.        </p>    }</div>

可以看到我创建了三个helpers,分别对应不同样式的模块,只需指定标题title作为参数,添加标准html内容作为模块显示内容。

使用这个功能,需要做如下工作:

建立Infrastructure 目录并在其下添加HtmlHeper.cs 文件,代码如下:

using System;using System.Web.Mvc;namespace MVCThemedApp1.Infrastructure{    public static class HtmlHelper    {        public static ThemedBox NoticeBlock(this System.Web.Mvc.HtmlHelper html, string title)        {            TagBuilder divBuilder = new TagBuilder("div");            divBuilder.AddCssClass("block notice");            html.ViewContext.Writer.Write(String.Format("{0}<h4>{1}</h4>", divBuilder.ToString(TagRenderMode.StartTag), title));            ThemedBox theBox = new ThemedBox(html.ViewContext);            return theBox;        }        public static ThemedBox InnerBlock(this System.Web.Mvc.HtmlHelper html, string title)        {            TagBuilder blockDiv = new TagBuilder("div");            blockDiv.AddCssClass("block");            html.ViewContext.Writer.Write(blockDiv.ToString(TagRenderMode.StartTag));            TagBuilder divBuilder = new TagBuilder("div");            divBuilder.AddCssClass("sidebar-block");            html.ViewContext.Writer.Write(String.Format("{0}<h4>{1}</h4>", divBuilder.ToString(TagRenderMode.SelfClosing), title));            ThemedBox theBox = new ThemedBox(html.ViewContext,2);            return theBox;        }        public static ThemedBox SimpleBlock(this System.Web.Mvc.HtmlHelper html, string title)        {            TagBuilder blockDiv = new TagBuilder("div");            blockDiv.AddCssClass("block");            html.ViewContext.Writer.Write(String.Format("{0}<h3>{1}</h3>", blockDiv.ToString(TagRenderMode.StartTag), title));            TagBuilder contentDiv = new TagBuilder("div");            contentDiv.AddCssClass("content");            html.ViewContext.Writer.Write(contentDiv.ToString(TagRenderMode.SelfClosing));            ThemedBox theBox = new ThemedBox(html.ViewContext,2);            return theBox;        }    }}

下一步,在infrastructure目录下添加ThemedBox.cs

using System;using System.Web;using System.Web.Mvc;using System.IO;namespace MVCThemedApp1.Infrastructure{    public class ThemedBox : IDisposable    {        private bool _disposed;        private readonly ViewContext _viewContext;        private readonly TextWriter _writer;        private int NumberOfClosingDivs = 1;        public ThemedBox(HttpResponseBase httpResponse)        {            if (httpResponse == null)            {                throw new ArgumentNullException("httpResponse");            }            _writer = httpResponse.Output;        }        public ThemedBox(ViewContext viewContext, int numberOfClosingDivs=1)        {            if (viewContext == null)            {                throw new ArgumentNullException("viewContext");            }            NumberOfClosingDivs = numberOfClosingDivs;            _viewContext = viewContext;            _writer = viewContext.Writer;        }        public void Dispose()        {            Dispose(true /* disposing */);            GC.SuppressFinalize(this);        }        protected virtual void Dispose(bool disposing)        {            if (!_disposed)            {                _disposed = true;                for (int i = 1; i <= NumberOfClosingDivs; i++)                {                    _writer.Write("</div>");                }                                if (_viewContext != null)                {                    _viewContext.OutputClientValidation();                }            }        }    }}