2009-11-10 12 views
8

piszę kawałek kodu, aby dodać tag link do tagu głowy w kodzie za ... czyliSamozamykająca się kontrola generyczna HTML?

HtmlGenericControl css = new HtmlGenericControl("link"); 

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

aby spróbować osiągnąć coś jak ...

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

I używam HtmlGenericControl do osiągnięcia tego ... problem mam jest to, że kontrola ultimatly pobiera renderowane jako ...

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

cant wydają się znaleźć to, czego mi brakuje, aby nie spowodować, że dodatek itional </link>, założyłem, że powinna to być własność obiektu.

Czy brakuje mi czegoś lub czy to nie jest możliwe za pomocą tej kontroli?

Dzięki

+0

jakiś szczególny powód chcesz krótki formularz? Za jedną, a może za garść linków na stronę, myślę, że narzut garstki bajtów byłby znikomy. – Lazarus

+2

Ponieważ używanie długiej formy niektórych tagów powoduje problemy w niektórych przeglądarkach. To dobry pomysł. Niektóre wersje (chyba wszystkie?) IE nie radzą sobie z

erikkallen

+0

@Lazarus: erikkallen jest poprawny z problemem przeglądarki, chcę zapewnić najlepszą kompatybilność. –

Odpowiedz

9

myślę, że trzeba czerpać z HtmlGenericControl i zastąpić metodę Render.

Będziesz wtedy mógł samemu napisać "/>" (lub możesz użyć stałejHtmlTextWriter).

Edit: Here's an example (w VB)

1

Alternatywnie można użyć Page.ParseControl(string), który daje kontrolę z taką samą zawartością jak struny mijamy.

W rzeczywistości robię dokładnie to samo w moim bieżącym projekcie. Oczywiście wymaga to odniesienia do bieżącej strony (handler), ale nie powinno to stanowić problemu.

Jedyne zastrzeżenie w tej metodzie, jak ja to widzę, jest to, że nie dostaniesz żadnego „oo”, podejścia do tworzenia kontrolę (np. control.Attributes.Add("href", theValue") itp)

0

Właśnie stworzyliśmy rozwiązanie ten, oparty na Ragaraths komentarzy na innym forum:

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

przesłonić HtmlGenericControl z tym

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

Podczas próby obejścia obejścia dla umbraco.library:RegisterStyleSheetFile(string key, string url) skończyło się na tym samym pytaniu co OP i znalazłem następujące.

Zgodnie z specs, znacznik Link jest elementem pustym. Nie może zawierać żadnych treści, ale może samo się zamknąć. Walidator W3C nie zatwierdził <link></link> jako poprawnego html5.

Widocznie

HtmlGenericControl css = new HtmlGenericControl("link"); 

staje się domyślnie jako <link></link>.Korzystanie z konkretną kontrolę dla Link tagu rozwiązać mój problem:

HtmlLink css = new HtmlLink(); 

Produkuje dopłata <link/> który został zatwierdzony jako poprawny XHTML i HTML5.

Oprócz Link, System.Web.UI.HtmlControls zawiera klasy dla innych pustych kontroli element, na przykład img, wejście i meta.

+1

Jest to najwyraźniej najczystszy sposób na tworzenie poprawnego html ... dlaczego używać kontroli generycznej, gdy dostarczana jest klasa HtmlLink? – Nick

0

delikatniehacky sposób.

  • Umieść element sterujący wewnątrz elementu PlaceHolder.
  • W kodzie za przejęciem metody renderowania PlaceHolder.
  • Renderuj zawartość PlaceHolders dokładnie tak, jak chcesz.

Jest to specyficzne dla strony/kontroli i nie wymaga żadnych przesłonięć. Ma więc minimalny wpływ na resztę twojego systemu.

<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); 
     } 
    } 
} 
Powiązane problemy