流畅的界面用于呈现HTML [英] Fluent interface for rendering HTML

查看:149
本文介绍了流畅的界面用于呈现HTML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用HtmlTextWriter呈现HTML在我看来并不令人难以置信,但如果您在Web表单中实现网页控件,那么您必须使用它。我认为有可能为此创建一个流畅的接口,它的读取更像是它输出的HTML。我想知道人们对我到目前为止的语法有什么看法。

  public void Render(HtmlTextWriter (HtmlTextWriterAttribute.Id,id] [HtmlTextWriterAttribute.Name,name] [HtmlTextWriterAttribute.Class ,class])
.Tag(HtmlTextWriterTag.Span)
.Text(Lorem)
.EndTag()
.Tag(HtmlTextWriterTag.Span)
.Text(ipsum)
.EndTag()
.EndTag();

$ / code>

Tag,Text和EndTag是HtmlTextWriter类,它返回它所需的实例,以便可以调用链接。传递给用于第一次调用标记的重载的lambda的参数是一个HtmlAttributeManager,它是一个简单的类,它封装了一个HtmlTextWriter以提供一个索引器,它接受一个HtmlTextWriterAttribute和一个字符串值并返回实例该呼叫可以被链接。我也有这个类的最常用属性的方法,比如Name,Class和Id,这样你就可以写出如下的第一个调用:

  .Tag(HtmlTextWriterTag.Div,e => e.Id(id)。Name(name)。Class(class))

稍长一点的例子:

  public void Render(HtmlTextWriter writer)
{
writer
.Tag(HtmlTextWriterTag.Div,a => a.Class(someClass,someOtherClass))
.Tag(HtmlTextWriterTag.H1).Text(Lorem)。EndTag()
.Tag(HtmlTextWriterTag.Select,t => t.Id(fooSelect)。Name(fooSelect ).class(selectClass))
.Tag(HtmlTextWriterTag.Option,t => t [HtmlTextWriterAttribute.Value,1] [HtmlTextWriterAttribute.Title,Selects the number 1.])
.Text(1)
.EndTag(HtmlTextWriterTag.Option)
.Tag(HtmlTextWriterTag.Option,t => t [HtmlTextWrit (HtmlTextWriterAttribute.Title,选择数字2。))
.Text(2)
.EndTag(HtmlTextWriterTag.Option)
.Tag (HtmlTextWriterTag.Option,t => t [HtmlTextWriterAttribute.Value,3] [HtmlTextWriterAttribute.Title,选择数字3.])
.Text(3)
.EndTag(HtmlTextWriterTag.Option)
.EndTag(HtmlTextWriterTag.Select)
.EndTag(HtmlTextWriterTag.Div);
}

希望您能够解密此代码段输出的HTML,至少这是主意。



请给我任何关于如何改进语法的想法,或许更好的方法名称,也许还有其他一些方法。 >

编辑:
我认为不用流利的界面就可以看到相同的代码片段,比较起来可能很有趣:

  public void RenderUsingHtmlTextWriterStandardMethods(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class,someClass someOtherClass);
writer.RenderBeginTag(HtmlTextWriterTag.Div);

writer.RenderBeginTag(HtmlTextWriterTag.H1);
writer.Write(Lorem);
writer.RenderEndTag();

writer.AddAttribute(HtmlTextWriterAttribute.Id,fooSelect);
writer.AddAttribute(HtmlTextWriterAttribute.Name,fooSelect);
writer.AddAttribute(HtmlTextWriterAttribute.Class,selectClass);
writer.RenderBeginTag(HtmlTextWriterTag.Select);

writer.AddAttribute(HtmlTextWriterAttribute.Value,1);
writer.AddAttribute(HtmlTextWriterAttribute.Title,选择数字1.);
writer.RenderBeginTag(HtmlTextWriterTag.Option);
writer.Write(1);
writer.RenderEndTag();

writer.AddAttribute(HtmlTextWriterAttribute.Value,2);
writer.AddAttribute(HtmlTextWriterAttribute.Title,选择数字2);
writer.RenderBeginTag(HtmlTextWriterTag.Option);
writer.Write(2);
writer.RenderEndTag();

writer.AddAttribute(HtmlTextWriterAttribute.Value,3);
writer.AddAttribute(HtmlTextWriterAttribute.Title,选择数字3);
writer.RenderBeginTag(HtmlTextWriterTag.Option);
writer.Write(3);
writer.RenderEndTag();

writer.RenderEndTag();

writer.RenderEndTag();
}

编辑:
我应该更明确一些,其中一个目标是它应该尽可能减少开销,这就是为什么我限制使用lambda表达式。此外,起初我使用了一个代表标签的类,以便在渲染之前通过语法构建类似于DOM树的东西,但语法非常相似。我放弃了这个解决方案,因为它产生了轻微的内存开销。在使用HtmlAttributeManager类时仍然存在一些这样的情况,我一直在考虑使用扩展方法来附加属性,但是我不能使用索引器语法,也扩展了HtmlTextWriter的接口甚至更多。

解决方案

我希望能够拥有这种语法:

 使用(var w = new HtmlTextWriter(sw))
{
w.Html()
.Head()
.Script()
.Attributes(new {type =text / javascript,src =somescript.cs})
.WriteContent(var foo ='bar')
.EndTag()
.EndTag()
.Body()
.P()
.WriteContent(某些内容)
.EndTag()
.EndTag()
.EndTag();





$ b为了达到这个目的,我在HtmlTextWriter中添加了扩展方法,尽管容器可能会更合适(我更感兴趣的是首先使它工作!)
感觉懒惰,我不想为每个可用标签写一个方法,所以我使用codegend方法通过迭代System.Web.UI.HtmlTextWriterTag枚举来创建t4模板。标签属性使用匿名对象进行管理;代码基本上反映了匿名类型,抽出属性并将它们转换为属性,我认为它们的结果语法非常干净。



代码实体结果:

  using System; 
使用System.Web.UI;
使用System.Collections.Generic;


///< summary>
/// HtmlTextWriter的扩展
///< / summary>
公共静态部分类HtmlWriterTextTagExtensions
{
static Stack< Tag> tags = new Stack< Tag>();



///< summary>
///打开未知的Html标记
///< / summary>
public static HtmlTextWriter Unknown(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(新标签(未知,null));
回报作家;
}

///< summary>
///打开一个Html标签
///< / summary>
public static HtmlTextWriter A(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(a,null));
回报作家;
}

///< summary>
///打开Acronym Html标记
///< / summary>
public static HtmlTextWriter首字母缩写词(这个HtmlTextWriter作家)
{
WritePreceeding(writer);
tags.Push(new Tag(acronym,null));
回报作家;
}

///< summary>
///打开地址Html标记
///< / summary>
public static HtmlTextWriter Address(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(新标签(address,null));
回报作家;
}

///< summary>
///打开Area Html标记
///< / summary>
public static HtmlTextWriter Area(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(area,null));
回报作家;
}

///< summary>
///打开一个B Html标记
///< / summary>
public static HtmlTextWriter B(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(b,null));
回报作家;
}

///< summary>
///打开Base Html标记
///< / summary>
public static HtmlTextWriter Base(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(base,null));
回报作家;
}

///< summary>
///打开Basefont Html标签
///< / summary>
public static HtmlTextWriter Basefont(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(basefont,null));
回报作家;
}

///< summary>
///打开Bdo Html标记
///< / summary>
public static HtmlTextWriter Bdo(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(bdo,null));
回报作家;
}

///< summary>
///打开Bgsound Html标记
///< / summary>
public static HtmlTextWriter Bgsound(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(bgsound,null));
回报作家;
}

///< summary>
///打开Big Html标记
///< / summary>
public static HtmlTextWriter Big(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(big,null));
回报作家;
}

///< summary>
///打开一个Blockquote Html标记
///< / summary>
public static HtmlTextWriter Blockquote(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(blockquote,null));
回报作家;
}

///< summary>
///打开Body Html标记
///< / summary>
public static HtmlTextWriter Body(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(body,null));
回报作家;
}

///< summary>
///打开一个Br Html标记
///< / summary>
public static HtmlTextWriter Br(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(br,null));
回报作家;
}

///< summary>
///打开Button Html标记
///< / summary>
public static HtmlTextWriter Button(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(新标签(button,null));
回报作家;
}

///< summary>
///打开Caption Html标记
///< / summary>
public static HtmlTextWriter Caption(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(caption,null));
回报作家;
}

///< summary>
///打开一个Center Html标记
///< / summary>
public static HtmlTextWriter Center(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(center,null));
回报作家;
}

///< summary>
///打开Cite Html标记
///< / summary>
public static HtmlTextWriter Cite(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(cite,null));
回报作家;
}

///< summary>
///打开代码Html标记
///< / summary>
public static HtmlTextWriter Code(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(新标签(code,null));
回报作家;
}

///< summary>
///打开Col Html标记
///< / summary>
public static HtmlTextWriter Col(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(col,null));
回报作家;
}

///< summary>
///打开Colgroup Html标记
///< / summary>
public static HtmlTextWriter Colgroup(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(新标签(colgroup,null));
回报作家;
}

///< summary>
///打开Dd Html标记
///< / summary>
public static HtmlTextWriter Dd(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(dd,null));
回报作家;
}

///< summary>
///打开Del Html标记
///< / summary>
public static HtmlTextWriter Del(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(del,null));
回报作家;
}

///< summary>
///打开一个Dfn Html标记
///< / summary>
public static HtmlTextWriter Dfn(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(新标签(dfn,null));
回报作家;
}

///< summary>
///打开Dir Html标记
///< / summary>
public static HtmlTextWriter Dir(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(dir,null));
回报作家;
}

///< summary>
///打开Div Html标记
///< / summary>
public static HtmlTextWriter Div(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(新标签(div,null));
回报作家;
}

///< summary>
///打开一个Dl Html标记
///< / summary>
public static HtmlTextWriter Dl(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(dl,null));
回报作家;
}

///< summary>
///打开一个Dt Html标记
///< / summary>
public static HtmlTextWriter Dt(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(dt,null));
回报作家;
}

///< summary>
///打开Em Html标记
///< / summary>
public static HtmlTextWriter Em(this HtmlTextWriter writer)
{
WritePreceeding(writer);
tags.Push(new Tag(em,null));
回报作家;
}


Rendering HTML with the HtmlTextWriter isn't incredibly intuitive in my opinion, but if you're implementing web controls in web forms it's what you have to work with. I thought that it might be possible to create a fluent interface for this that reads a bit more like the HTML it outputs. I would like to know what people think of the syntax that I've come up with so far.

    public void Render(HtmlTextWriter writer)
    {
        writer
            .Tag(HtmlTextWriterTag.Div, e => e[HtmlTextWriterAttribute.Id, "id"][HtmlTextWriterAttribute.Name,"name"][HtmlTextWriterAttribute.Class,"class"])
                .Tag(HtmlTextWriterTag.Span)
                    .Text("Lorem")
                .EndTag()
                .Tag(HtmlTextWriterTag.Span)
                    .Text("ipsum")
                .EndTag()
            .EndTag();        
    }

"Tag", "Text" and "EndTag" are extension methods for the HtmlTextWriter class that returns the instance it takes in so that calls can be chained. The argument passed to the lambda used in the overload used by the first call to "Tag" is a "HtmlAttributeManager", which is simple class that wraps an HtmlTextWriter to provide an indexer that takes an HtmlTextWriterAttribute and a string value and returns the instance so that calls can be chained. I also have methods on this class for the most common attributes, such as "Name", "Class" and "Id" so that you could write the first call above as follows:

.Tag(HtmlTextWriterTag.Div, e => e.Id("id").Name("name").Class("class"))

A little longer example:

public void Render(HtmlTextWriter writer)
{
    writer
        .Tag(HtmlTextWriterTag.Div, a => a.Class("someClass", "someOtherClass"))
            .Tag(HtmlTextWriterTag.H1).Text("Lorem").EndTag()
            .Tag(HtmlTextWriterTag.Select, t => t.Id("fooSelect").Name("fooSelect").Class("selectClass"))
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "1"][HtmlTextWriterAttribute.Title, "Selects the number 1."])
                    .Text("1")
                .EndTag(HtmlTextWriterTag.Option)
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "2"][HtmlTextWriterAttribute.Title, "Selects the number 2."])
                    .Text("2")
                .EndTag(HtmlTextWriterTag.Option)
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "3"][HtmlTextWriterAttribute.Title, "Selects the number 3."])
                    .Text("3")
                .EndTag(HtmlTextWriterTag.Option)
            .EndTag(HtmlTextWriterTag.Select)
        .EndTag(HtmlTextWriterTag.Div);
}

Hopefully you'll be able to "decipher" what HTML this snippet outputs, at least that's the idea.

Please give me any thoughts on how the syntax can be improved upon, maybe better method names, maybe some other approach all together.

Edit: I thought it might be interesting to see what the same snippet would look like without the use of the fluent interface, for comparison:

public void RenderUsingHtmlTextWriterStandardMethods(HtmlTextWriter writer)
{
    writer.AddAttribute(HtmlTextWriterAttribute.Class, "someClass someOtherClass");
    writer.RenderBeginTag(HtmlTextWriterTag.Div);

    writer.RenderBeginTag(HtmlTextWriterTag.H1);
    writer.Write("Lorem");
    writer.RenderEndTag();

    writer.AddAttribute(HtmlTextWriterAttribute.Id, "fooSelect");
    writer.AddAttribute(HtmlTextWriterAttribute.Name, "fooSelect");
    writer.AddAttribute(HtmlTextWriterAttribute.Class, "selectClass");
    writer.RenderBeginTag(HtmlTextWriterTag.Select);

    writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
    writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 1.");
    writer.RenderBeginTag(HtmlTextWriterTag.Option);
    writer.Write("1");
    writer.RenderEndTag();

    writer.AddAttribute(HtmlTextWriterAttribute.Value, "2");
    writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 2.");
    writer.RenderBeginTag(HtmlTextWriterTag.Option);
    writer.Write("2");
    writer.RenderEndTag();

    writer.AddAttribute(HtmlTextWriterAttribute.Value, "3");
    writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 3.");
    writer.RenderBeginTag(HtmlTextWriterTag.Option);
    writer.Write("3");
    writer.RenderEndTag();

    writer.RenderEndTag();

    writer.RenderEndTag();
}

EDIT: I should probably be a little more explicit in that one of the goals with this is that it should incur as little overhead as possible, this is why I've limited the use of lambdas. Also at first I used a class that represented a tag so that something similar to a DOM-tree was built by the syntax before the rendering, the syntax was very similar though. I abandoned this solution for the slight memory overhead it incurs. There are still some of this present in the use of the HtmlAttributeManager class, I have been thinking about using extension methods for the appending of attributes also, but the I can't use the indexer-syntax, also it bloats the interface of the HtmlTextWriter even more.

解决方案

I wanted to be able to have this kind of syntax:

using (var w = new HtmlTextWriter(sw))
        {
            w.Html()
                .Head()
                    .Script()
                        .Attributes(new { type = "text/javascript", src = "somescript.cs" })
                        .WriteContent("var foo='bar'")
                    .EndTag()
                .EndTag()
                .Body()
                    .P()
                        .WriteContent("some content")
                    .EndTag()
                .EndTag()
            .EndTag();
        }

In order to acheive this I've added extension methods to the HtmlTextWriter although a container would probably be more appropriate (I was more interested in getting it to work first of all!) Feeling lazy, I didn't want to write a method for each of the available tags, so I codegend the methods using a t4 template by iterating through the System.Web.UI.HtmlTextWriterTag enum. Tag attributes are managed using anonymous objects; the code basically reflects on the anonymous type, pulls out the properties and turns them into attributes which I think gives the resultant syntax a very clean appearance.

The codegend result:

using System;
using System.Web.UI;
using System.Collections.Generic;


/// <summary>
///  Extensions for HtmlTextWriter
/// </summary>
public static partial class HtmlWriterTextTagExtensions
{
    static Stack<Tag> tags = new Stack<Tag>();



        /// <summary>
        ///  Opens a Unknown Html tag
        /// </summary>
        public static HtmlTextWriter Unknown(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("Unknown",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a A Html tag
        /// </summary>
        public static HtmlTextWriter A(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("a",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Acronym Html tag
        /// </summary>
        public static HtmlTextWriter Acronym(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("acronym",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Address Html tag
        /// </summary>
        public static HtmlTextWriter Address(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("address",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Area Html tag
        /// </summary>
        public static HtmlTextWriter Area(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("area",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a B Html tag
        /// </summary>
        public static HtmlTextWriter B(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("b",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Base Html tag
        /// </summary>
        public static HtmlTextWriter Base(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("base",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Basefont Html tag
        /// </summary>
        public static HtmlTextWriter Basefont(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("basefont",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Bdo Html tag
        /// </summary>
        public static HtmlTextWriter Bdo(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("bdo",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Bgsound Html tag
        /// </summary>
        public static HtmlTextWriter Bgsound(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("bgsound",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Big Html tag
        /// </summary>
        public static HtmlTextWriter Big(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("big",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Blockquote Html tag
        /// </summary>
        public static HtmlTextWriter Blockquote(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("blockquote",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Body Html tag
        /// </summary>
        public static HtmlTextWriter Body(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("body",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Br Html tag
        /// </summary>
        public static HtmlTextWriter Br(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("br",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Button Html tag
        /// </summary>
        public static HtmlTextWriter Button(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("button",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Caption Html tag
        /// </summary>
        public static HtmlTextWriter Caption(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("caption",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Center Html tag
        /// </summary>
        public static HtmlTextWriter Center(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("center",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Cite Html tag
        /// </summary>
        public static HtmlTextWriter Cite(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("cite",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Code Html tag
        /// </summary>
        public static HtmlTextWriter Code(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("code",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Col Html tag
        /// </summary>
        public static HtmlTextWriter Col(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("col",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Colgroup Html tag
        /// </summary>
        public static HtmlTextWriter Colgroup(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("colgroup",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Dd Html tag
        /// </summary>
        public static HtmlTextWriter Dd(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("dd",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Del Html tag
        /// </summary>
        public static HtmlTextWriter Del(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("del",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Dfn Html tag
        /// </summary>
        public static HtmlTextWriter Dfn(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("dfn",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Dir Html tag
        /// </summary>
        public static HtmlTextWriter Dir(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("dir",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Div Html tag
        /// </summary>
        public static HtmlTextWriter Div(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("div",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Dl Html tag
        /// </summary>
        public static HtmlTextWriter Dl(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("dl",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Dt Html tag
        /// </summary>
        public static HtmlTextWriter Dt(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("dt",  null));
            return writer;
        }

        /// <summary>
        ///  Opens a Em Html tag
        /// </summary>
        public static HtmlTextWriter Em(this HtmlTextWriter writer)
        {
            WritePreceeding(writer);
            tags.Push(new Tag("em",  null));
            return writer;
        }

这篇关于流畅的界面用于呈现HTML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆