2009-11-09 50 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>

希望它是有道理的!