有没有人知道如何让嵌套服务器控件接受嵌套的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>
答案 0 :(得分: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>
答案 1 :(得分:0)
试试这个:
[ToolboxData("..."), ParseChildren(false), PersistChildren(true)]
public class CustomServerControl : WebControl, INamingContainer
{
}
答案 2 :(得分:0)
这个基本的目的是拥有一个自定义Generic标记库,在这种情况下,它将与底层对象模型对话。对象模型负责将文章分成各自的部分,即标题,模糊,图像,评论等。在这种情况下,我正在考虑它们的集合,并通过指定内部标记,您基本上应用过滤器到你希望看到的部分文章的哪些部分。
<uc1:Section runat="server">
<HeadLine></HeadLine>
<Blurb></Blurb>
<Body></Body>
</uc1:Section>
根据用户仅通过标记他需要的内容指定的内容,相应的内容将被写入前端。
现在这个效果非常好,除了在一两个案例中你实际上需要某种内部结构到文章的每个部分,然后将它投射到整个集合上,就像有一个{{1}标题应该放在一个<table>
中,其余的放到另一个<td>
希望它有意义!!