2009-11-09 89 views
0

有誰知道如何使嵌套的服務器控件接受嵌套的HTML,而不從服務器端「注入」它,即。嵌套服務器控件允許嵌套的HTML

<uc1:CustomServerControl runat="server"> 
    <NestedControl></NestedControl> 
    <NestedControl2></NestedControl2> 
</uc1:CustomServerControl> 

,但要做到這一點:

<uc1:CustomServerControl runat="server"> 
    <div> 
     <NestedControl> 
      <a href="#"></a> 
     </NestedControl> 
     <NestedControl2></NestedControl2> 
    </div> 
</uc1:CustomServerControl> 

回答

1

嘗試這種情況:

Section.cs:

[ToolboxData("<{0}:Section runat=\"server\" />")] 
public class Section : WebControl, INamingContainer 
{ 
    private SectionPartCollection _parts; 

    [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)] 
    public SectionPartCollection Parts 
    { 
     get 
     { 
      if (this._parts == null) 
      { 
       this._parts = new SectionPartCollection(); 
       if (this.IsTrackingViewState) 
        ((IStateManager)this._parts).TrackViewState(); 
      } 
      return this._parts; 
     } 
    } 

    [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)] 
    public ITemplate LayoutTemplate { get; set; } 

    protected override void CreateChildControls() 
    { 
     base.CreateChildControls(); 

     if (this.LayoutTemplate != null) 
     { 
      this.LayoutTemplate.InstantiateIn(this); 

      foreach (SectionPart part in this.Parts) 
      { 
       Control placeHolder = this.FindControl(part.PlaceHolderID); 
       if (placeHolder != null) 
        if (part.ContentTemplate != null) 
         part.ContentTemplate.InstantiateIn(placeHolder); 
      } 
     } 
    } 

    protected override void LoadViewState(object savedState) 
    { 
     object[] states = (object[])savedState; 

     base.LoadViewState(states[0]); 

     if (states[1] != null) 
      ((IStateManager)this.Parts).LoadViewState(states[1]); 
    } 

    protected override object SaveViewState() 
    { 
     object[] states = new object[2]; 

     states[0] = base.SaveViewState(); 

     if (this._parts != null) 
      states[1] = ((IStateManager)this.Parts).SaveViewState(); 

     return states; 
    } 

    protected override void TrackViewState() 
    { 
     base.TrackViewState(); 

     if (this._parts != null) 
      ((IStateManager)this._parts).TrackViewState(); 
    } 
} 

SectionPart.cs:

[DefaultProperty("PartName")] 
public class SectionPart : IStateManager 
{ 
    private StateBag _viewState; 
    private bool _isTrackingViewState; 

    [DefaultValue("")] 
    public string PlaceHolderID 
    { 
     get { return (string)this.ViewState["PlaceHolderID"] ?? string.Empty; } 
     set { this.ViewState["PlaceHolderID"] = value; } 
    } 

    [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)] 
    public ITemplate ContentTemplate { get; set; } 

    public void SetDirty() 
    { 
     if (this._viewState != null) 
      this.ViewState.SetDirty(true); 
    } 

    [Browsable(false)] 
    protected StateBag ViewState 
    { 
     get 
     { 
      if (this._viewState == null) 
      { 
       this._viewState = new StateBag(false); 
       if (this._isTrackingViewState) 
        ((IStateManager)this._viewState).TrackViewState(); 
      } 
      return this._viewState; 
     } 
    } 

    protected virtual bool IsTrackingViewState 
    { 
     get { return this._isTrackingViewState; } 
    } 

    protected virtual void LoadViewState(object state) 
    { 
     if (state != null) 
      ((IStateManager)this.ViewState).LoadViewState(state); 
    } 

    protected virtual object SaveViewState() 
    { 
     if (this._viewState != null) 
      return ((IStateManager)this._viewState).SaveViewState(); 
     return null; 
    } 

    protected virtual void TrackViewState() 
    { 
     this._isTrackingViewState = true; 
     if (this._viewState != null) 
      ((IStateManager)this._viewState).TrackViewState(); 
    } 

    bool IStateManager.IsTrackingViewState 
    { 
     get { return this.IsTrackingViewState; } 
    } 

    void IStateManager.LoadViewState(object state) 
    { 
     this.LoadViewState(state); 
    } 

    object IStateManager.SaveViewState() 
    { 
     return this.SaveViewState(); 
    } 

    void IStateManager.TrackViewState() 
    { 
     this.TrackViewState(); 
    } 

} 

SectionPartCollection.cs:

public class SectionPartCollection : StateManagedCollection 
{ 

    public SectionPart this[int index] 
    { 
     get { return (SectionPart)((IList)this)[index]; } 
    } 

    public void Add(SectionPart part) 
    { 
     if (part == null) 
      throw new ArgumentNullException("part"); 

     ((IList)this).Add(part); 
    } 

    public void Insert(int index, SectionPart part) 
    { 
     if (part == null) 
      throw new ArgumentNullException("part"); 

     ((IList)this).Insert(index, part); 
    } 

    public void Remove(SectionPart part) 
    { 
     if (part == null) 
      throw new ArgumentNullException("part"); 

     ((IList)this).Remove(part); 
    } 

    public void RemoveAt(int index) 
    { 
     ((IList)this).RemoveAt(index); 
    } 

    protected override void SetDirtyObject(object o) 
    { 
     ((SectionPart)o).SetDirty(); 
    } 

} 

實施例:

<uc:Section ID="Section1" runat="server"> 
    <LayoutTemplate> 
     <table> 
      <tr> 
       <td id="TitlePlaceHolder" runat="server"> 
       </td> 
      </tr> 
      <tr> 
       <td id="BodyPlaceHolder" runat="server"> 
       </td> 
      </tr> 
     </table> 
    </LayoutTemplate> 
    <Parts> 
     <uc:SectionPart PlaceHolderID="TitlePlaceHolder"> 
      <ContentTemplate> 
       <span>Title</span> 
      </ContentTemplate> 
     </uc:SectionPart> 
     <uc:SectionPart PlaceHolderID="BodyPlaceHolder"> 
      <ContentTemplate> 
       <p> 
        Some content...</p> 
      </ContentTemplate> 
     </uc:SectionPart> 
    </Parts> 
</uc:Section> 
+0

你給了我一些想法,我會在實施後回來給你 – 2009-11-09 12:07:26

0

試試這個:

[ToolboxData("..."), ParseChildren(false), PersistChildren(true)] 
public class CustomServerControl : WebControl, INamingContainer 
{ 
} 
+0

我的問題是,我必須設置ParseChildren(true),因爲主要的servercontrol包含需要呈現的嵌套控件,我需要將處理控制兒童的功能作爲屬性並呈現html。 – 2009-11-09 07:33:44

+0

我認爲,這是不可能的。正如你在第二個代碼片段中所展示的那樣,你將一個CustomServerControl屬性放到一個div的內部HTML中,而服務器控制的這個HTML不能解析它們。我不知道你想要做什麼,爲什麼?如果你解釋了ServerControl任務,也許我可以幫忙。 – 2009-11-09 08:14:09

0

這個basicly的目的是爲了有一個自定義的通用標籤庫,whick在這種情況下,會說話一個潛在的對象模型。 objectmodel負責將文章分解成各自的部分,即標題,blurb,圖像,註釋等。在這種情況下,我正在處理它們的集合,並通過指定內部標記,基本上將過濾器應用到您想要查看的部分中的文章部分。

<uc1:Section runat="server">  
    <HeadLine></HeadLine>  
    <Blurb></Blurb>  
    <Body></Body> 
    </uc1:Section> 

根據用戶指定的內容,只需標記他需要的任何內容,相應的內容就會寫入前端。

現在這個工作非常好,除了在一種或兩種情況下,您實際上需要某種內部結構到每個文章的各個部分,然後將其投影到整個集合中,例如有一個<table>標題應該進入一個<td>和其餘的到另一個<td>

希望它是有道理的!