C# 呈现嵌套服务器控件
这应该相对容易。我不知道我为什么要与之抗争,但谷歌不能帮我找到一个我想做的事情的例子 我正在用LIs构建一个简单的ULs嵌套结构的导航/菜单。放置在页面上的父对象称为NavController。它有一个Navitem集合 因此,我几乎让NavController处理构建基本UI、创建CSS和JavaScript。它还为最顶层的LIs创建基础UL。根据我的研究和理解,UI的创建应该在CreateChildControls方法中完成 这是我的密码:C# 呈现嵌套服务器控件,c#,.net,.net-2.0,controls,C#,.net,.net 2.0,Controls,这应该相对容易。我不知道我为什么要与之抗争,但谷歌不能帮我找到一个我想做的事情的例子 我正在用LIs构建一个简单的ULs嵌套结构的导航/菜单。放置在页面上的父对象称为NavController。它有一个Navitem集合 因此,我几乎让NavController处理构建基本UI、创建CSS和JavaScript。它还为最顶层的LIs创建基础UL。根据我的研究和理解,UI的创建应该在CreateChildControls方法中完成 这是我的密码: protected override void C
protected override void CreateChildControls()
{
Controls.Clear();
this.Page.RegisterClientJavaScript("~/Resources/Script/SideNav.js");
_ClientObject = this.GetClientJavaScriptObject("SideNav", this.ClientID);
Controls.Add(_BaseContainer);
HtmlGenericControl innerContents = this.BuildBaseContainer();
this.BuildList(innerContents);
_ClientObject.AddParameter("BaseContainerID", _BaseContainer.ClientID, true);
_ClientObject.AddParameter("ImgId", _SideBarTabImg.ClientID, true);
_ClientObject.AddParameter("SideBarContentsId", _SideBarContents.ClientID, true);
base.CreateChildControls();
}
BuildList方法实际上构建顶级LIs。我不确定该方法是如何调用的,但我可以看出它是。在BuildList函数中,我将NavItem对象添加到innerContents的控件集合中
首先,这是正确的吗?在UL的内部放置另一个自定义服务器控件(注意,该自定义控件基本上是呈现LI;稍后将对此进行详细介绍)
从未为NaviItem调用CreateChildControls。在互联网上四处查看后,似乎是因为我从来没有给EnsureChildControl打过电话。这让我很困惑,因为它只会在ChildControlsCreated属性为false时激发。一旦运行该属性,该属性将变为真。如果我在NavItem上有一个文本和Href,并确保在设置其中一个控件时调用RechildControl,那么如何将另一个控件的值放入任何子控件中
为了堵塞一些屏幕空间,以下是我目前为止为NavItem编写的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace AthletesCafe.Web.WebControls.SideNav
{
[ToolboxData("<{0}:NavItem runat=server></{0}:NavItem>")]
public class NavItem : ExtendedWebControl
{
private string _Text;
private string _Value;
private IList<NavItem> _ChildItems = new List<NavItem>();
private HtmlGenericControl _ListItem = new HtmlGenericControl("LI");
private HtmlAnchor _Link = new HtmlAnchor();
private HtmlGenericControl _SubList = new HtmlGenericControl("UL");
public string Text
{
get
{
EnsureChildControls();
return _Text;
}
set
{
EnsureChildControls();
_Text = value;
_Link.InnerText = _Text;
}
}
public string Value
{
get
{
EnsureChildControls();
return _Value;
}
set
{
EnsureChildControls();
_Value = value;
_Link.HRef = _Value;
}
}
protected override void CreateChildControls()
{
Controls.Clear();
Controls.Add(_ListItem);
_ListItem.Controls.Add(_Link);
base.CreateChildControls();
}
public NavItem AddChildItem(string text, string url)
{
EnsureChildControls();
NavItem newItem = new NavItem();
newItem.Text = text;
newItem.Value = url;
_ChildItems.Add(newItem);
this.BuildSubList();
return newItem;
}
private void BuildSubList()
{
_SubList.Controls.Clear();
if (_ChildItems.Count > 0)
{
if (!_ListItem.Controls.Contains(_SubList))
_ListItem.Controls.Add(_SubList);
foreach (NavItem item in _ChildItems)
_SubList.Controls.Add(item);
}
}
protected override void Render(HtmlTextWriter writer)
{
RenderContents(writer);
}
protected override void RenderContents(HtmlTextWriter writer)
{
_ListItem.RenderControl(writer);
//base.RenderContents(writer);
}
public override string ToString()
{
EnsureChildControls();
return _Text + " - " + _Value;
}
}
}
一旦重写CreateChildControls(),您基本上就要负责确保正确创建嵌套控件 您的方法似乎相当标准,但是,对于简单的属性,我认为您不需要调用EnsureChildControl()。如果您从函数上的MSDN文档中获取了此信息,请再看一看-它们给出的“Text”属性示例是从其子控件之一检索文本值,这意味着属性访问器需要确保子控件存在 您无法保证有人何时可以访问您的控件,这就是为什么在对控件集合中的控件进行任何访问之前,您会先进行EnsureChildControl()调用的原因。在正常页面生命周期中,当ASP.net着手将复合控件添加到页面时,将调用CreateChildControls()。如果没有人触碰您的控件,并且它没有数据绑定或任何东西,则在加载第一页时预呈现之前,可能不会发生这种情况 在后续回发中,将在ViewState处理期间调用CreateChildControls,或者任何代码都可能触发复合控件以开始创建其子控件。例如,FindControl()将自动执行此操作—这可能发生在OnInit()中
希望有帮助。我想你说得对。看看我添加的列表代码,你能解释一下为什么我将NavItem添加到UL中时,它永远不会呈现。通过渲染,我的意思是我不知道应该将创建其子控件的代码放在其中的什么位置。我想这也是同样的方法。
HtmlGenericControl list = new HtmlGenericControl("UL");
innerContents.Controls.Add(list);
foreach (NavItem item in _Items)
{
list.Controls.Add(item);
}