我不想使用asp.net的TreeView控件。 我想创建一个具有多模板支持的自定义模板数据绑定控件,如 -
<asp:MtNavigationControl>
<ItemTemplate>
...
...
</ItemTemplate>
<SelectedItemTemplate>
...
...
</SelectedItemTemplate>
<ParentItemTemplate>
...
...
</ParentSelectedItemTemplate>
<SelectedParentItemTemplate>
...
...
</SelectedParentSelectedItemTemplate>
</asp:MtNavigationControl>
我的数据就像 -
class Employee
{
string EmployeeName
List<Employee> Employees
}
有谁知道如何完成它?请帮忙!!!
答案 0 :(得分:0)
基本上,我的TreeBranches只是Branch对象的集合类。与您的Employee示例非常相似。模板只不过是以下内容:
<h2><a href='<%= this.NavigationUrl %>'><%= this.Title %></a></h2>
<asp:PlaceHolder ID="phContents" runat="server" EnableViewState="true"></asp:PlaceHolder>
它会产生一个低于它们的LI的UL。如果存在嵌套分支,则新的UL将包含在作为父级的LI中。这可以尽可能深。
使用System; 使用System.Collections.Generic; 使用System.Linq; 使用System.Web.UI; 使用System.Web.UI.WebControls; 使用System.Text; 使用System.ComponentModel; 使用System.Collections;
命名空间Website.Controls { public partial class 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
}