該死的,我想我可能已經找到了我正在尋找的東西。我有同樣的問題,我有近乎完整的。我不確定這是我的班級(TreeBranches)還是下面的班級。似乎在初始渲染上效果很好。但是,每個回發似乎都會渲染兩次。我已經嘗試了像Controls.Clear()這樣的東西,但.UniqueID似乎總是用於第二組控制。
基本上,我的TreeBranches只是分支對象的集合類。非常類似於您的員工示例。該模板只不過是以下內容:
<h2><a href='<%= this.NavigationUrl %>'><%= this.Title %></a></h2>
<asp:PlaceHolder ID="phContents" runat="server" EnableViewState="true"></asp:PlaceHolder>
它將生成UL下面有LI的。如果存在嵌套分支,那麼作爲父母的LI中將包含新的UL。這可以儘可能深。
using System; using System.Collections.Generic;使用System.Linq的 ; using System.Web.UI; using System.Web.UI.WebControls; using System.Text; using System.ComponentModel;使用System.Collections的 ;
命名空間Website.Controls { 公共部分類HeirarchicalList:System.Web.UI.UserControl {
private ITemplate _layoutTemplate = null;
private ITemplate _itemTemplate = null;
private string _LayoutPlaceholderID = "";
#region Public Properties
public TreeBranches DataSource { get; set; }
/// <summary>
/// Gets or Sets the Header for this controls <h2> element.
/// </summary>
[PersistenceMode(PersistenceMode.Attribute)]
public string Title { get; set; }
/// <summary>
/// Gets or Sets the Class name for the outermost LayoutTemplate item.
/// </summary>
[PersistenceMode(PersistenceMode.Attribute)]
public string RootClass { get; set; }
/// <summary>
/// Gets or Sets the Headers link for this controls <h2> element.
/// </summary>
[PersistenceMode(PersistenceMode.Attribute)]
public string NavigationUrl { get; set; }
/// <summary>
/// Gets or Sets the local ID for the LayoutTemplates Placeholder control. Defaults to "layoutPlaceholder"
/// </summary>
[PersistenceMode(PersistenceMode.Attribute)]
public string LayoutPlaceholderID {
get { return string.IsNullOrWhiteSpace(this._LayoutPlaceholderID) ? "layoutPlaceholder" : this._LayoutPlaceholderID; }
set { this._LayoutPlaceholderID = value; }
}
[Browsable(false)]
[DefaultValue(null)]
[TemplateContainer(typeof(LayoutContainer))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate LayoutTemplate {
get { return _layoutTemplate; }
set { _layoutTemplate = value; }
}
[Browsable(false)]
[DefaultValue(null)]
[TemplateContainer(typeof(ItemContainer))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate ItemTemplate {
get { return _itemTemplate; }
set { _itemTemplate = value; }
}
#endregion Public Properties
public override void DataBind() {
if ((_itemTemplate != null) && (_layoutTemplate != null)) {
if (this.phContents.HasControls())
this.phContents.Controls.Clear(); // Clear any existing child controls.
LayoutContainer parent = new LayoutContainer(this.RootClass); // Apply the RootClass only to the Root item
_layoutTemplate.InstantiateIn(parent);
PlaceHolder ph = parent.FindControl(this.LayoutPlaceholderID) as PlaceHolder;
if (ph == null)
throw new FormatException(string.Format("Unable to find the LayoutTemplate's PlaceHolder object. Either one does not exist or the name {0} specified in the LayoutPlaceholderID does not match the ID of the PlaceHolder.", this.LayoutPlaceholderID));
this.RecurseBranches(this.DataSource.ToList(), ph);
this.phContents.Controls.Add(parent);
} else {
throw new FormatException("Both the LayoutTemplate and the ItemTemplate must be defined.");
} // if the template has been defined
base.DataBind();
}
/// <summary>
/// This method will take the List of Branches and generate an unordered list with however many branches are necessary.
/// </summary>
/// <param name="Branches"></param>
/// <param name="Canvas"></param>
private void RecurseBranches(List<Branch> Branches, Control Canvas) {
foreach (Branch branch in Branches) {
ItemContainer SingleItem = new ItemContainer(branch);
_itemTemplate.InstantiateIn(SingleItem);
if (branch.HasChildren) {
LayoutContainer NewGroup = new LayoutContainer(); // Notice no RootClass being passed in here
_layoutTemplate.InstantiateIn(NewGroup);
PlaceHolder NewCanvas = NewGroup.FindControl(this.LayoutPlaceholderID) as PlaceHolder;
PlaceHolder Parent = SingleItem.FindControl(this.LayoutPlaceholderID) as PlaceHolder;
this.RecurseBranches(branch.Children.ToList(), NewCanvas); // Add new Items to the Group
Parent.Controls.Add(NewGroup); // Add the new Group to its Parent Item
} // if there are any children to go under this node
Canvas.Controls.Add(SingleItem); // Add the current Item to the Canvas
} // foreach of the Branches to bind
} // RecurseBranches - Method
} // HeirarchicalList - Class
#region Container Classes
public class LayoutContainer : Control, INamingContainer {
public string RootClass { get; set; }
internal LayoutContainer() { }
internal LayoutContainer(string RootClass) {
this.RootClass = RootClass;
} // LayoutContainer - Constructor
} // LayoutContainer - Class
public class ItemContainer : Control, INamingContainer {
public Branch BranchItem { get; set; }
internal ItemContainer(Branch BranchItem) {
this.BranchItem = BranchItem;
} // ItemContainer - Constructor
} // ItemContainer - Class
#endregion
}