I have a self-referencing table and I want to visualize it using:

 <ol>
   <li>
   </li>
 </ol>

I want to create a custom server data-bound control with templates, I have read the MSDN article:

http://msdn.microsoft.com/en-us/library/aa479322.aspx

But I think that, I have to use different aproach and inherit the

HierarchicalDataBoundControl

or implement

IHierarchicalDataSource

But I cannot find any examples, or something to read from.

Can someone point me to a book or an article, or explain it to me in steps how it needs to be done.

有帮助吗?

解决方案

A summary of what is required is this:

A Control which extends HierarchicalDataSourceControl AND DataSourceControl that implements IHeirarchicalDataSource. Believe me working from the documentation provided took A LOT of trial and error but in the end it is worth it. Mines been on hold but shortly I'll complete a project using this which will be able to bind to any n depth structure + navigate it in code using Node.GetParent().GetChildren().Where .. etc. It's complicted and may be overkill for what you need and you may revert back to repeater. Given the posting length allowed at stackoverflow I can't give you full code listing (some 100k chars)

To give you a flavour of whats in my other code here is the generic IHierachicalDataSourceControl:

    #region Generic Hierachical DatasourceControl
    /// <summary>
    /// Datasource control
    /// </summary>
    public class GenericHierachicalDataSourceControl<TDataContext, TNode, TEntity> : HierarchicalDataSourceControl, IHierarchicalDataSource
        where TDataContext : DataContext, new()
        where TNode : class,PNS.GenericLinqNodeHeirachy<TDataContext, TNode, TEntity>.IHeirachicalNode, new()
        where TEntity : class,PNS.GenericLinqNodeHeirachy<TDataContext, TNode, TEntity>.IHeirachyNodeEntity, new()
    {
        NodeDataSourceView view;
        protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath)
        {
            view = new NodeDataSourceView(viewPath);
            return view;
        }

        public class NodeDataSourceView : HierarchicalDataSourceView
        {
            private string _viewPath;
            public NodeDataSourceView(string viewPath)
            {
                _viewPath = viewPath;
            }
            public override IHierarchicalEnumerable Select()
            {
                var hierarchy = new HierarchicalEnumerable();
                List<TNode> topNodes;
                if (String.IsNullOrEmpty(_viewPath))
                {
                    //get all top level nodes (ones without parents)
                    topNodes = GenericLinqNodeHeirachy<TDataContext, TNode, TEntity>.NodesDAL.GetTopLevelNodes().ToList();
                }
                else
                {
                    //get the last node in the path
                    string[] nodes = _viewPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                    topNodes = new List<TNode>();

                    topNodes.Add(GenericLinqNodeHeirachy<TDataContext, TNode, TEntity>.NodesDAL.GetNode(nodes[nodes.Length - 1]));
                }
                //for each node in the path
                foreach (var node in topNodes)
                {
                    if (node.Entity != null)
                    {
                        hierarchy.Add(node.Entity);
                    }
                }
                return hierarchy;
            }
        }
        public class HierarchicalEnumerable : List<TEntity>, IHierarchicalEnumerable
        {
            public HierarchicalEnumerable()
                : base()
            {
            }
            public IHierarchyData GetHierarchyData(object enumeratedItem)
            {
                return enumeratedItem as IHierarchyData;
            }
        }
    }

and another part:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Web.UI.HtmlControls;

namespace BootstrapProject.CodeBase
{
    public class GenericHierarchicalDataboundControl : HierarchicalDataBoundControl
    {
        private string _textField;
        public string TextField
        {
            get { return _textField; }
            set { _textField = value; }
        }
        protected override string TagName
        {
            get
            {
                return "div";
            }
        }
        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Div;
            }
        }
        protected override void CreateChildControls()
        {
            if (null != Page && Page.IsPostBack && null != ViewState["_!DataBound"])
            {
                this.RequiresDataBinding = true;
                this.EnsureDataBound();
            }
        }
        protected override void PerformDataBinding()
        {
            IHierarchicalEnumerable dataSource = GetData(string.Empty).Select();
            this.PerformDataBinding(0, this.Controls, dataSource);
            this.MarkAsDataBound();
        }
        protected virtual void PerformDataBinding(int level, ControlCollection controls, IHierarchicalEnumerable dataSource)
        {
            if (null != dataSource)
            {
                //controls.Clear();
                HtmlGenericControl ul = new HtmlGenericControl("ul");
                foreach (object value in dataSource)
                {
                    var itemData = dataSource.GetHierarchyData(value);
                    Control item = CreateAndBindControl(level, value);
                    ul.Controls.Add(item);

                    var data = dataSource.GetHierarchyData(value);
                    if (data != null && data.HasChildren)
                    {
                        IHierarchicalEnumerable childData = data.GetChildren();
                        PerformDataBinding(1 + level, item.Controls, childData);
                    }

                    controls.Add(ul);
                }
            }
        }
        protected virtual Control CreateAndBindControl(int level, object dataItem)
        {
            HtmlGenericControl li = new HtmlGenericControl("li");
            string text = String.Empty;
            if (!String.IsNullOrEmpty(TextField))
            {
                text = DataBinder.GetPropertyValue(dataItem, TextField).ToString();
            }
            else
            {
                text = dataItem.ToString();
            }
            li.Attributes.Add("rel", text);
            li.Controls.Add(new HyperLink { Text = text });
            return li;
        }
    }
}

And finally:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using BootstrapProject.CodeBase.DAL;
using PNS;

namespace BootstrapProject.CodeBase
{
    public class NodeDataSourceControl : HierarchicalDataSourceControl, IHierarchicalDataSource
    {

        NodeDataSourceView view;

        protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath)
        {
            view = new NodeDataSourceView(viewPath);
            return view;
        }
    }

    public class NodeDataSourceView : HierarchicalDataSourceView
    {

        private string _viewPath;
        public NodeDataSourceView(string viewPath)
        {
            _viewPath = viewPath;
        }

        public override IHierarchicalEnumerable Select()
        {
            var hierarchy = new CMSPageHierarchicalEnumerable();
            List<DAL.Node> topNodes;
            if (String.IsNullOrEmpty(_viewPath))
            {
                //get all top level nodes (ones without parents)
                topNodes = CMS.NodesDAL.GetTopLevelNodes().ToList();
            }
            else
            {
                //get the last node in the path
                string[] nodes = _viewPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                topNodes = new List<DAL.Node>();
                topNodes.AddRange(CMS.NodesDAL.GetNode(nodes[nodes.Length - 1]).NodeChildren);
            }
            //for each node in the path
            foreach (var node in topNodes)
            {
                if (node.Page != null)
                {
                    hierarchy.Add(node.Page);
                }
            }
            return hierarchy;
        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top