创建层次结构自定义服务器控件

时间:2011-12-12 16:48:02

标签: asp.net visual-studio c#-4.0 custom-controls databound

我有一个自引用表,我希望使用以下内容对其进行可视化:

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

我想用模板创建一个自定义服务器数据绑定控件,我已阅读过MSDN文章:

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

但我认为,我必须使用不同的方法并继承

HierarchicalDataBoundControl

或实施

IHierarchicalDataSource

但我找不到任何例子或其他东西可供阅读。

有人可以指点我一本书或一篇文章,或者按步骤向我解释它是如何完成的。

1 个答案:

答案 0 :(得分:0)

需要的摘要是:

一个控件,它扩展了实现IHeirarchicalDataSource的HierarchicalDataSourceControl和DataSourceControl。相信我从提供的文档工作了很多的试验和错误,但最终它是值得的。矿井已被搁置但不久我将完成一个项目使用它将能够绑定到任何n深度结构+使用Node.GetParent()在代码中导航它.GetChildren()。其中​​..等它是复杂的并且可能对你所需要的东西来说太过分了,你可能会回到转发器上。鉴于stackoverflow允许的发布长度,我不能给你完整的代码列表(大约100k字符)

为了让您了解我在其他代码中的最新信息,这里是通用的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;
            }
        }
    }

和另一部分:

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;
        }
    }
}

最后:

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;
        }
    }
}