开发者

asp.net + How to create custom multi-templated tree databound control?

I dont want to use asp.net's TreeView control. I want to create a custom template databound control with multi template support like -

<asp:MtNavigationControl>

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

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

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

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

</asp:MtNavigationControl>

My data is like -

class Employee
{
       string EmployeeName
       List<Employee> Employees
}

Does anyone know how to accomplish it? Please help开发者_JAVA百科 !!!


Damn, I thought I might have found what I was looking for. I have the same question and I have it NEARLY complete. I am not sure if it is my class (TreeBranches) or the below class. Seems to work great on the initial render. But then each postback it seems to render things twice. I have tried things like Controls.Clear() but the .UniqueID's seem to always be for a second set of control.

Basically, my TreeBranches is just a collection class for Branch objects. Quite similar to your Employee example. The Template is nothing more than the following:

<h2><a href='<%= this.NavigationUrl %>'><%= this.Title %></a></h2>
<asp:PlaceHolder ID="phContents" runat="server" EnableViewState="true"></asp:PlaceHolder>

It will generate a UL with LI's below them. And if there is a nested Branch, a new UL will be contained in the LI that is the parent. This can be as deep as possible.

using System; using System.Collections.Generic; using System.Linq; using System.Web.UI; using System.Web.UI.WebControls; using System.Text; using System.ComponentModel; using System.Collections;

namespace 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
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜