自我关闭Html通用控件?
我正在写一些代码来为后面的代码中的head标签添加一个链接标签…即
HtmlGenericControl css = new HtmlGenericControl("link"); css.Attributes["rel"] = "Stylesheet"; css.Attributes["type"] = "text/css"; css.Attributes["href"] = String.Format("/Assets/CSS/{0}", cssFile);
尝试实现类似……
我正在使用HtmlGenericControl实现这个…我遇到的问题是控件最终呈现为……
我似乎无法找到我不想渲染的附加 ,我认为它应该是对象的属性。
我错过了什么,或者这个控件不可能吗?
谢谢
我认为你必须从HtmlGenericControl
派生,并覆盖Render
方法。
然后你就可以自己写出“/>”(或者你可以使用HtmlTextWriter的SelfClosingTagEnd
常量)。
编辑: 这是一个例子 (在VB中)
在尝试为umbraco.library:RegisterStyleSheetFile(string key, string url)
写一个变通方法时umbraco.library:RegisterStyleSheetFile(string key, string url)
我最终得到了与OP相同的问题并找到了以下内容。
根据规范 , link标签是一个void元素。 它不能有任何内容,但可以自我关闭。 W3Cvalidation器未将validation为正确的html5。
显然地
HtmlGenericControl css = new HtmlGenericControl("link");
默认情况下呈现为 。 使用链接标记的特定控件解决了我的问题:
HtmlLink css = new HtmlLink();
它产生标记 ,它被validation为正确的xhtml和html5。
除了link之外 , System.Web.UI.HtmlControls还包含其他void元素控件的类,例如img , input和meta 。
或者,您可以使用Page.ParseControl(string)
,它为您提供与您传递的字符串相同内容的控件。
我实际上在我当前的项目中做了同样的事情。 当然它需要引用当前页面(处理程序),但这不应该造成任何问题。
正如我所看到的,这种方法中唯一需要注意的是,你没有得到任何“OO”方法来创建你的控件(例如control.Attributes.Add("href", theValue")
等)
我刚刚在另一个论坛上根据Ragaraths的评论为此创建了一个解决方案:
http://forums.asp.net/p/1537143/3737667.aspx
用这个覆盖HtmlGenericControl
protected override void Render(HtmlTextWriter writer) { if (this.Controls.Count > 0) base.Render(writer); // render in normal way else { writer.Write(HtmlTextWriter.TagLeftChar + this.TagName); // render opening tag Attributes.Render(writer); // Add the attributes. writer.Write(HtmlTextWriter.SelfClosingTagEnd); // render closing tag } writer.Write(Environment.NewLine); // make it one per line }
略带苛刻的方式。
- 将控件放在PlaceHolder元素中。
- 在劫持PlaceHolder的render方法背后的代码中。
- 完全按照您的意愿渲染PlaceHolders内容。
这是特定于页面/控件的,不需要任何覆盖。 因此它对您系统的其余部分影响最小。
protected void Page_Init(object sender, EventArgs e) { myPlaceHolder.SetRenderMethodDelegate(ClosingRenderMethod); } protected void ClosingRenderMethod(HtmlTextWriter output, Control container) { var voidTags = new HashSet(StringComparer.InvariantCultureIgnoreCase) { "br", "hr", "link", "img" }; foreach (Control child in container.Controls) { var generic = child as HtmlGenericControl; if (generic != null && voidTags.Contains(generic.TagName)) { output.WriteBeginTag(generic.TagName); output.WriteAttribute("id", generic.ClientID); generic.Attributes.Render(output); output.Write(HtmlTextWriter.SelfClosingTagEnd); } else { child.RenderControl(output); } } }