0

我建立我這自CompositeControl控制HTML控件

繼承

的原因控制是能夠對多個在線一致的內容區域(HTML元素)第一自定義服務器控件我們開發的應用程序。的

因此而不必經常打出來:

<div class="titleBar"> 
</div> 
<div class="actionBar"> 
</div> 
<div class="workspace"> 
</div> 

的開發人員可以添加如下服務器控制:

<custom:Workspace id="..." runat="server" Title="MyTitle"> 
    <TitleBar> 
     Here is the title 
    </TitleBar> 
    <ActionBar> 
     <asp:button id="..." runat="server" Title="MyButton" /> 
    </ActionBar> 
    <Content> 
     <asp:DataGrid id="..." runat="server" /> 
    </Content> 
</custom:Workspace> 

我讀的文章在http://msdn.microsoft.com/en-us/library/ms178657.aspx和它的作品,但問題是......我不明白爲什麼。 (有沒有人有鏈接到一篇文章的外行人的版本,描述如何建立這些類型的服務器控件?)

我注意到的主要事情到目前爲止,是Asp.net呈現一堆SPAN元素,其中當然我不想要。

如何控制新的CompositeControl輸出的HTML?

感謝, 雅克

PS。這裏是我到目前爲止的代碼:

using System; 
using System.ComponentModel; 
using System.Drawing; 
using System.Security.Permissions; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.Design; 
namespace TemplatedServerControl 
{ 
    [DefaultProperty("Title")] 
    [ToolboxData("<{0}:Workspace runat=server></{0}:Workspace>")] 
    public class Workspace : CompositeControl 
    { 
     #region FIELDS 
     private ITemplate _TitleBarTemplateValue; 
     private ITemplate _ActionBarTemplateValue; 
     private TemplateOwner _TitleBarOwnerValue; 
     private TemplateOwner _ActionBarOwnerValue; 
     #endregion 
     #region PROPERTY - TitleBarOwner 
     [Browsable(false), 
     DesignerSerializationVisibility(
     DesignerSerializationVisibility.Hidden)] 
     public TemplateOwner TitleBarOwner 
     { 
      get 
      { 
       return _TitleBarOwnerValue; 
      } 
     } 
     #endregion 
     #region PROPERTY - ActionBarOwner 
     [Browsable(false), 
     DesignerSerializationVisibility(
     DesignerSerializationVisibility.Hidden)] 
     public TemplateOwner ActionBarOwner 
     { 
      get 
      { 
       return _ActionBarOwnerValue; 
      } 
     } 
     #endregion 
     #region PROPERTY - Title 
     [Bindable(true)] 
     [Category("Appearance")] 
     [DefaultValue("[Provide the title for the workspace]")] 
     [Localizable(true)] 
     public string Title 
     { 
      get 
      { 
       String s = (String)ViewState["Title"]; 
       return ((s == null) ? "[" + this.ID + "]" : s); 
      } 

      set 
      { 
       ViewState["Text"] = value; 
      } 
     } 
     #endregion 
     #region PROPERTY - TitleBar 
     [Browsable(false), 
     PersistenceMode(PersistenceMode.InnerProperty), 
     DefaultValue(typeof(ITemplate), ""), 
     Description("Control template"), 
     TemplateContainer(typeof(Workspace))] 
     public virtual ITemplate TitleBar 
     { 
      get 
      { 
       return _TitleBarTemplateValue; 
      } 
      set 
      { 
       _TitleBarTemplateValue = value; 
      } 
     } 
     #endregion 
     #region PROPERTY - ActionBar 
     [Browsable(false), 
     PersistenceMode(PersistenceMode.InnerProperty), 
     DefaultValue(typeof(ITemplate), ""), 
     Description("Control template"), 
     TemplateContainer(typeof(Workspace))] 
     public virtual ITemplate ActionBar 
     { 
      get 
      { 
       return _ActionBarTemplateValue; 
      } 
      set 
      { 
       _ActionBarTemplateValue = value; 
      } 
     } 
     #endregion 
     #region METHOD - CreateChildControls() 
     protected override void CreateChildControls() 
     { 
      //base.CreateChildControls(); 
      Controls.Clear(); 

      _TitleBarOwnerValue = new TemplateOwner(); 
      _ActionBarOwnerValue = new TemplateOwner(); 

      ITemplate temp1 = _TitleBarTemplateValue; 
      ITemplate temp2 = _ActionBarTemplateValue; 

      temp1.InstantiateIn(_TitleBarOwnerValue); 
      temp2.InstantiateIn(_ActionBarOwnerValue); 

      this.Controls.Add(_TitleBarOwnerValue); 
      this.Controls.Add(_ActionBarOwnerValue); 
     } 
     #endregion 
     #region METHOD - RenderContents(HtmlTextWriter writer) 
     protected override void RenderContents(HtmlTextWriter writer) 
     { 
      base.RenderContents(writer); 
     } 
     #endregion 
    } 

    [ToolboxItem(false)] 
    public class TemplateOwner : WebControl 
    { 
    } 
} 

回答

1

額外<span>元素從TemplateOwner控制來,因爲一個WebControl(其中TemplateOwner從繼承)呈現<span>標籤默認。你可以改變TemplateOwner指定標籤來顯示:

public class TemplateOwner : WebControl 
{ 
    public TemplateOwner() : 
     base(HtmlTextWriterTag.Div) 
    { 
    } 
} 

但你並不需要創建自己的類以使用模板。例如,您可以使用Panel控件:

private Panel _TitleBarPanel; 
private Panel _ActionBarPanel; 

protected override void CreateChildControls() 
{ 
    _TitleBarPanel = new Panel { CssClass = "titleBar" }; 
    _TitleBarTemplateValue.InstantiateIn(_TitleBarPanel); 
    this.Controls.Add(_TitleBarPanel); 

    _ActionBarPanel = new Panel { CssClass = "actionBar" }; 
    _ActionBarTemplateValue.InstantiateIn(_ActionBarPanel); 
    this.Controls.Add(_ActionBarPanel); 
} 
+0

感謝邁克爾真的欣賞它編程控制。我會試一試。你有沒有機會鏈接到一個教程,將更詳細地解釋複合控件和模板? – Jacques 2012-04-05 07:13:38

+0

我不知道任何關於我頭頂的物品。如果您有更多問題,請隨時詢問。 :-) – 2012-04-05 13:44:42

0

一個簡單的解決方案,我們使用PlaceHolder控件。 與CompositeControl類似,這是一個容器控件。 但與CompositeControl不同的是,它根本不呈現任何內容 - 不包含任何內容或標記。

這意味着你不能以編程方式引用整個控件,就像你可以使用CompositeControl一樣,但取決於你在做什麼,這可能不是必需的。

每個子控件都會有一個唯一的ID,因此,您可以參考的孩子(與事件等的交易)