2009-11-10 3 views
8

Я пишу немного кода, чтобы добавить ссылку тег в голову тег в коде позади ... т.е.Самозакрывающийся общий элемент управления Html?

HtmlGenericControl css = new HtmlGenericControl("link"); 

css.Attributes["rel"] = "Stylesheet"; 
css.Attributes["type"] = "text/css"; 
css.Attributes["href"] = String.Format("/Assets/CSS/{0}", cssFile); 

, чтобы попытаться достичь что-то вроде ...

<link rel="Stylesheet" type="text/css" href="/CSS/Blah.css" /> 

I Я использую в HtmlGenericControl для достижения этой цели ... вопрос я имею то, что управление ultimatly визуализируется, как ...

<link rel="Stylesheet" type="text/css" href="/CSS/Blah.css"></link> 

Я не могу показаться, чтобы найти то, что мне не хватает, чтобы не оказывать надстройку itional </link>, я предположил, что это должно быть свойство объекта.

Я что-то упустил или это невозможно с этим контролем?

Благодаря

+0

Любая конкретная причина, по которой вы хотите получить короткую форму? Для одного или, может быть, нескольких ссылок на страницу я думаю, что накладные расходы на несколько байтов были бы незначительными. – Lazarus

+2

Потому что использование длинной формы некоторых тегов вызывает проблемы в некоторых браузерах. Это хорошая идея. Некоторые версии (возможно, все?) IE не справляются с

erikkallen

+0

@Lazarus: erikkallen верен с проблемой браузера, я хочу обеспечить лучшую совместимость. – 2009-11-10 14:20:29

ответ

9

Я думаю, что вы должны были бы получить от HtmlGenericControl, и переопределить метод Render.

Вы можете сами выписать «/>» (или вы можете использовать константу SelfClosingTagEnd HtmlTextWriter).

Edit: Here's an example (в VB)

1

В качестве альтернативы вы можете использовать Page.ParseControl(string), который дает вам контроль с тем же содержанием строки вы передаете.

Я на самом деле делаю то же самое в своем текущем проекте. Конечно, для этого требуется ссылка на текущую страницу (обработчик), но это не должно создавать никаких проблем.

Единственное ограничение в этом методе, как я вижу, что вы не получаете «ОО» -подход для создания вашего контроля (например, control.Attributes.Add("href", theValue") и т.д.)

0

Я только что создал решение для это, основываясь на Ragaraths комментариев в другом форуме:

http://forums.asp.net/p/1537143/3737667.aspx

Override в 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 
} 
8

При попытке написать обходной путь для umbraco.library:RegisterStyleSheetFile(string key, string url) я столкнулся с тем же вопросом, что и OP, и нашел следующее.

В соответствии с specs, ссылка тег является элементом пустоты. Он не может иметь никакого контента, но может быть закрыт сам. Валидатор W3C не подтвердил <link></link> как правильный html5.

Видимо

HtmlGenericControl css = new HtmlGenericControl("link"); 

визуализируется по умолчанию как <link></link>.Используя определенный элемент управления для ссылки тегя решить мою проблему:

HtmlLink css = new HtmlLink(); 

Он производит наценка <link/>, который был утвержден в качестве правильного и html5 XHTML.

В дополнении к ссылке, System.Web.UI.HtmlControls содержит классы для других пустот управления элементом, такие как IMG, входа и меты.

+1

Это, безусловно, самый чистый способ создания допустимого html ... зачем использовать общий контроль, когда предоставляется класс HtmlLink? – Nick

0

слегка хакерский путь.

  • Поместите управление внутри элемента PlaceHolder.
  • В коде за градом используется метод рендеринга PlaceHolder.
  • Измените содержимое PlaceHolders точно так, как вы пожелаете.

Это страница/элемент управления и не требует каких-либо переопределений. Таким образом, это оказывает минимальное влияние на остальную часть вашей системы.

<asp:PlaceHolder ID="myPlaceHolder" runat="server"> 
    <hr id="someElement" runat="server" /> 
</asp:PlaceHolder> 

protected void Page_Init(object sender, EventArgs e) 
{ 
    myPlaceHolder.SetRenderMethodDelegate(ClosingRenderMethod); 
} 

protected void ClosingRenderMethod(HtmlTextWriter output, Control container) 
{ 
    var voidTags = new HashSet<string>(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); 
     } 
    } 
} 
Смежные вопросы