所需内容的摘要如下:
扩展 HierarchicalDataSourceControl 和实现 IHeirarchicalDataSource 的 DataSourceControl 的控件。相信我根据提供的文档工作需要大量的试验和错误,但最终还是值得的。地雷被搁置,但很快我将使用它完成一个项目,该项目将能够绑定到任何 n 深度结构 + 使用 Node.GetParent().GetChildren().Where .. 等在代码中导航它。这很复杂,可能对你需要的东西太过分了,你可能会恢复到中继器。鉴于 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;
}
}
}