【问题标题】:asp.net + How to create custom multi-templated tree databound control?asp.net + 如何创建自定义多模板树数据绑定控件?
【发布时间】:2010-04-05 14:59:50
【问题描述】:

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

<asp:MtNavigationControl>

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

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

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

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

</asp:MtNavigationControl>

我的数据是这样的 -

class Employee
{
       string EmployeeName
       List<Employee> Employees
}

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

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    该死,我以为我可能找到了我要找的东西。我有同样的问题,我几乎完成了。我不确定它是我的班级(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.Collections.Generic; 使用 System.Linq; 使用 System.Web.UI; 使用 System.Web.UI.WebControls; 使用 System.Text; 使用 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
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 2011-06-05
      • 2016-03-25
      • 1970-01-01
      相关资源
      最近更新 更多