2009-03-26 5 views
0

비교적 쉽습니다. 왜 내가 그걸로 고투하고 있는지 모르겠지만, 구글은 내가하고 싶은 일의 예를 찾도록 도와 줄 수 없다.렌더링 중첩 서버 컨트롤

LI가있는 UL의 간단한 중첩 구조에서 내비게이션/메뉴를 작성합니다. 페이지에 배치 된 부모 개체는 NavController라고합니다. 그것은 NavItems의 모음을 가지고 있습니다.

그래서 NavController가 기본 UI를 작성하고 CSS 및 JavaScript를 작성하도록 처리합니다. 또한 최상위 레벨의 LI에 대한 기본 UL을 작성합니다. 내 연구 및 이해에서 UI 작성은 CreateChildControls 메서드에서 수행되어야합니다.

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 방법은 실제로 최상위 수준의 LI를 구축 :

여기 내 코드입니다. 나는이 방법이 어떻게 불려지는지 확신하지 못한다.하지만 나는 그것이 있음을 알 수있다. BuildList 함수 내에서 innerContents의 Controls 컬렉션에 NavItem 객체를 추가합니다.

먼저 꺼내시겠습니까? 다른 맞춤 서버 컨트롤을 UL 내부에 배치합니다 (맞춤 컨트롤이 기본적으로 LI를 렌더링하는 경우주의해야 함, 나중에 자세히 설명).

CreateChildControls는 NavItem에 대해 절대로 호출되지 않습니다. 인터넷에서 주위를 둘러 본 후에는 결코 EnsureChildControls를 호출하지 않았기 때문에 그 것처럼 보였습니다. ChildControlsCreated 속성이 false 일 때만 실행되기 때문에 혼란 스럽습니다. 이 속성이 실행되면이 속성은 true가됩니다. NavItem에 Text 및 Href가 있고 EnsureChildControls 중 하나가 설정된 경우 Href가 있으면 다른 값은 하위 컨트롤에 어떻게 배치됩니까?

그냥 여기에 몇 가지 화면 공간을 방해하는 나는 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()를 오버라이드 (override)하면

HtmlGenericControl list = new HtmlGenericControl("UL"); 
innerContents.Controls.Add(list); 
foreach (NavItem item in _Items) 
{ 
    list.Controls.Add(item); 
} 

답변

2

, 당신은 기본적 중첩 된 컨트롤이 제대로 만들어 취득해야 할 책임이된다.

당신의 접근법은 꽤 표준적인 것처럼 보이지만 간단한 속성 때문에 EnsureChildControls()를 호출 할 필요가 없다고 생각합니다. 이 기능을 MSDN 문서에서 가져온 경우 다른 모양을 사용하십시오. "Text"속성 예제는 자식 컨트롤 중 하나에서 텍스트 값을 검색하는 것으로, 이는 속성 접근자가 자식을 확인해야 함을 의미합니다 컨트롤이 존재합니다.

누군가가 사용자의 컨트롤에 액세스 할 수있는 경우를 보장 할 수 없으므로 Controls 컬렉션의 컨트롤에 액세스하기 전에 EnsureChildControl() 호출을 사용하게됩니다. 정상적인 페이지 수명주기에서 CreateChildControls()는 ASP.net이 복합 컨트롤을 페이지에 추가 할 때 호출됩니다.아무도 컨트롤에 닿지 않고 데이터 바인딩 또는 아무것도하지 않으면 첫 번째 페이지로드시 PreRender가 실행될 때까지는 이런 일이 발생하지 않을 수 있습니다.

후속 포스트 백에서 ViewState 처리 중에 CreateChildControls가 호출되거나 모든 코드가 복합 컨트롤을 터치하여 자식 컨트롤을 만들기 시작할 수 있습니다. FindControl()은 자동으로이를 수행합니다. 예를 들어 OnInit()에서 이런 일이 발생할 수 있습니다.

희망이 있습니다. 나는 네가 제대로 된 것 같아.

+0

내가 추가 한 목록 코드를 보면, NavItem을 UL에 추가 할 때 왜 렌더링되지 않는지 설명 할 수 있습니까? 렌더링을 통해 자식 컨트롤을 만드는 코드를 어디에 배치해야하는지 모릅니다. 나는 그것이 같은 방법이 될 것이라고 생각할 것이다. –