2016-04-12 57 views
3

假設我有這個標記:HTML標籤如何轉換爲HtmlControl?

<asp:Repeater ID="Repeater1" runat="server"> 
    <ItemTemplate> 
     <a runat="server" id="myLink" href="<%# Container.DataItem %>">Here</a> 
    </ItemTemplate> 
</asp:Repeater> 

在代碼隱藏,我可以找出<a>轉換爲HtmlAnchor

private void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    HtmlAnchor myLink = (HtmlAnchor)Repeater1.FindControl("myLink"); 
} 

但如何編譯器知道<a>HtmlAnchor?它在編譯器中是硬編碼的嗎?

如果我寫

<asp:Repeater ID="Repeater1" runat="server"> 
    <ItemTemplate> 
     <Foo href="<%# Container.DataItem %>">Here</a> 
    </ItemTemplate> 
</asp:Repeater> 

,並希望<Foo>標籤轉換爲我HtmlFoo類,我如何做到這一點?

我只是想對幕後編譯過程有更深入的瞭解。

回答

2

您可以通過潛心鑽研Reference Source學到了很多關於ASP.NET的內部。

事實證明,從前綴的HTML標記HTMLLoader對象子類的映射是硬編碼在一個內部類稱爲HtmlTagNameToTypeMapper

static Hashtable _tagMap; 

Type ITagNameToTypeMapper.GetControlType(string tagName, IDictionary attributeBag) { 
    Type controlType; 

    if (_tagMap == null) { 
     Hashtable t = new Hashtable(10, StringComparer.OrdinalIgnoreCase); 
     t.Add("a", typeof(HtmlAnchor)); 
     t.Add("button", typeof(HtmlButton)); 
     t.Add("form", typeof(HtmlForm)); 
     // [and much more...] 
     _tagMap = t; 
    } 

    // [...] 
} 

GetControlType是所謂由另一個名爲MainTagNameToTypeMapper內部類:

int colonIndex = tagName.IndexOf(':'); 
if (colonIndex >= 0) { 
    // [...] 
} 
else { 
    // There is no prefix. 
    // Try the Html mapper if allowed 
    if (fAllowHtmlTags) { 
     return _htmlMapper.GetControlType(tagName, attribs); 
    } 
} 

有沒有公共API來註冊多個前綴的HTML控件類型。

在更加本地化的規模上,父控件可能定製如何解釋其子控件的標籤名稱。爲此,從ControlBuilder派生,覆蓋GetChildControlType,並使用[ControlBuilder(typeof(...)] attribute修飾父控制類。

+0

它是正是我想要的,非常感謝! – Gqqnbig

0

當您將runat="server"添加到ASP.NET中的控件時,HtmlControl(或其某個子類)的相應變量會自動添加到您的頁面(在設計器文件中)。這樣,您可以將該控件作爲變量訪問。對於大多數常見的HTML控件,有HtmlControl的子類(如用於錨點/鏈接標記的HtmlAnchor)。其他控件(如<div>)獲取HtmlGenericControl類型。對於那些,您將標籤(div)指定爲屬性。所以你的Foo標籤會得到像div一樣的變量:HtmlGenericControl,標籤爲「Foo」。

編輯:這是標準的HTML元素。如果創建一個ASP控件(如<asp:TextBox...>,然後將得到的變量將是一個子類,或者WebControl的,而不是HTMLControl時

+0

「你的Foo標籤會像div一樣:一個HtmlGenericControl類型的變量。」我可以改變它嗎?是否可以開發一個HtmlFoo類,以便將轉換爲HtmlFoo? – Gqqnbig

+0

您可以創建一個UserControl。標記將包含你喜歡的任何內容。然後在你的頁面上註冊UserControl,如下所示: '<%@ Register Src =「〜/ MyUserControl。ascx「TagPrefix =」uc「TagName =」MyUserControl「%> 然後在您的標記中,您可以使用如下的usercontrol: '' 它不會讓您添加' '並在幕後得到你的自定義類的實例,但只要你願意處理'<[prefix]:[name] ...>'的符號,那麼你可以或多或少地創建任何你如 – TheRotag

+0

我一直在做很多自定義/用戶控件,我正在尋求擺脫前綴的可能性,或者我用另一種方式問,編譯器知道是HtmlAnchor嗎?是否有一個屬性指定? – Gqqnbig

相關問題