asp.net +如何创建自定义多模板树数据绑定控件?

时间:2010-04-05 14:59:50

标签: asp.net

我不想使用asp.net的TreeView控件。 我想创建一个具有多模板支持的自定义模板数据绑定控件,如 -

<asp:MtNavigationControl>

    <ItemTemplate>
     ...
     ...
    </ItemTemplate>

    <SelectedItemTemplate>
     ...
     ...
    </SelectedItemTemplate>

    <ParentItemTemplate>
     ...
     ...
    </ParentSelectedItemTemplate>

    <SelectedParentItemTemplate>
     ...
     ...
    </SelectedParentSelectedItemTemplate>

</asp:MtNavigationControl>

我的数据就像 -

class Employee
{
       string EmployeeName
       List<Employee> Employees
}

有谁知道如何完成它?请帮忙!!!

1 个答案:

答案 0 :(得分:0)

该死的,我以为我可能找到了我想要的东西。我有同样的问题,我几乎完成了。我不确定它是我的班级(TreeBranches)还是下面的班级。似乎在初始渲染上工作得很好。但随后每次回发它似乎都会渲染两次。我尝试过类似Controls.Clear()的东西,但.UniqueID似乎总是用于第二组控件。

基本上,我的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
}