Создать иерархию настраиваемого серверного элемента управления - PullRequest
0 голосов
/ 12 декабря 2011

У меня есть таблица со ссылками на себя, и я хочу визуализировать ее, используя:

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

Я хочу создать собственный серверный элемент управления с привязкой к данным с помощью шаблонов. Я прочел статью MSDN:

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

Но я думаю, что я должен использовать другой подход и наследовать

HierarchicalDataBoundControl

или орудие

IHierarchicalDataSource

Но я не могу найти примеры или что-то почитать.

Может кто-нибудь указать мне на книгу или статью, или объяснить мне, как это нужно сделать, пошагово.

1 Ответ

0 голосов
/ 12 декабря 2011

Сводка того, что требуется, такова:

Элемент управления, расширяющий HierarchicalDataSourceControl AND DataSourceControl, который реализует IHeirarchicalDataSource.Поверьте мне, работа по предоставленной документации заняла ОЧЕНЬ много проб и ошибок, но в конце концов это того стоит.Шахты были приостановлены, но в скором времени я закончу проект, используя его, который сможет связываться с любой структурой глубины n + перемещаться по ней в коде с помощью Node.GetParent (). GetChildren (). Где ... и т. Д. Это сложно и можетбудьте излишними для того, что вам нужно, и вы можете вернуться к повторителю.Учитывая допустимую длину публикации в stackoverflow, я не могу дать вам полный список кодов (около 100 тыс. Символов)

Чтобы дать вам представление о том, что в моем другом коде, вот обобщенный 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;
        }
    }
}
...