[英]Xamarin Forms Nested flex layout with other controls not rendering properly
[英]Rendering Nested Server Controls
這應該相對容易。 我不知道為什么要為此苦苦掙扎,但是Google無法幫助我找到我想做的事的例子。
我正在構建帶有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函數中,我將NavItem對象添加到innerContents的Controls集合中。
首先,這是正確的嗎? 將另一個自定義服務器控件放置在UL內部(需要注意的是,自定義控件基本上是呈現LI;稍后將對此進行詳細說明)?
永遠不會為NavItem調用CreateChildControls。 在Internet上四處逛逛之后,似乎是因為我從未打電話給確保兒童控件。 這使我感到困惑,因為它只會在ChildControlsCreated屬性為false時才會觸發。 一旦運行,此屬性將變為true。 如果我在NavItem上設置了Text和Href並在設置了其中一個時調用了sureChildControls,那么如何將另一個的值放入任何子控件中?
只是為了阻塞一些屏幕空間,這是我到目前為止為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;
}
}
}
我不明白為什么我不能只在其公共屬性中設置值和文本,然后在渲染之前使用某種方法或方式將其放入控件中。
拜托,請給我指出正確的方法。 我需要一堆這樣的小控件,基本上可以采用相同的方法。 我將很快啟動一個基本的工具欄,該信息將有所幫助!
編輯-放置代碼以顯示清單建築物以供澄清:
HtmlGenericControl list = new HtmlGenericControl("UL");
innerContents.Controls.Add(list);
foreach (NavItem item in _Items)
{
list.Controls.Add(item);
}
重寫CreateChildControls()之后,您基本上將負責確保正確創建嵌套控件。
您的方法似乎很標准,但是,對於您的簡單屬性,我認為您不需要調用SecureChildControls()。 如果您是從該函數的MSDN文檔中挑選的,請再看一看-他們提供的“ Text”屬性示例正在從其子控件之一中檢索文本值,這意味着屬性訪問器需要確保該子控件存在控件。
您無法保證何時有人可以訪問您的控件,這就是為什么您要在對Controls集合中的控件進行任何訪問之前先放入SecureChildControl()調用的原因。 在正常的頁面生命周期中,當ASP.net將您的復合控件添加到頁面時,將調用CreateChildControls()。 如果沒有人觸摸您的控件並且沒有進行數據綁定或任何操作,則在第一頁上的PreRender加載之前,可能不會發生這種情況。
在后續的回發中,將在ViewState處理期間調用CreateChildControls,否則任何代碼都可能觸發復合控件以開始創建其子控件。 例如,FindControl()將自動執行此操作-這可能發生在OnInit()中。
希望能有所幫助。 我認為您在正確的軌道上。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.