前言 :
之前发布了一篇[ASP.NET] : HierarchicalObjectDataSource
本篇是它的Part2,内容没有新的东西。
只是把上一篇发表的对象,套用一些Design Patterns。
来达到异种数据的数据系结。
一般写ASP.NET使用TreeView,大多使用XmlDataSource或是SiteMapDataSource做数据系结,不然就是依照数据去程序动态建立TreeNode。
HierarchicalObjectDataSource 封装了阶层式数据系结的复杂运算,让TreeView的数据系结开发变的可行。
依照这两篇HierarchicalObjectDataSource的文章思路继续开发下去,相信会有更多的延伸应用。
执行结果 :
下图为底下所有范例程序代码执行的结果。上半部表格将数据内容条列 ,下半部树状选单将数据内容显示为树状。
树状对象数据系结 :
树状对象数据系结,主要是使用Iterator这个Pattern来将树状数据做扁平化处理。
namespace WebApplication1 { public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (this.IsPostBack == false) { IEnumerable<DemoData> demoDataEnumerable = this.CreateDemoDataEnumerable(); IEnumerable<IHierarchicalObject> demoDataObjectEnumerable = new DemoDataObjectEnumerable(demoDataEnumerable); GridView1.DataSource = demoDataObjectEnumerable; GridView1.DataBind(); TreeView1.DataSource = new HierarchicalObjectDataSource(demoDataObjectEnumerable); TreeView1.DataBind(); } } private IEnumerable<DemoData> CreateDemoDataEnumerable() { DemoData demoData1; DemoData demoData2; DemoData demoData3; List<DemoData> demoDataList = new List<DemoData>(); demoData1 = new DemoData("AAA", "Id_AAA", "Name_AAA"); demoDataList.Add(demoData1); demoData1 = new DemoData("BBB", "Id_BBB", "Name_BBB"); demoData2 = new DemoData("DDD", "Id_DDD", "Name_DDD"); demoData3 = new DemoData("EEE", "Id_EEE", "Name_EEE"); demoData1.ChildrenList.Add(demoData2); demoData2.ChildrenList.Add(demoData3); demoDataList.Add(demoData1); demoData1 = new DemoData("CCC", "Id_CCC", "Name_CCC"); demoDataList.Add(demoData1); return demoDataList; } public class DemoData { // Properties private readonly string _path; private readonly string _id; private readonly string _name; private readonly List<DemoData> _childrenList; // Construction public DemoData(string path, string id, string name) { Require#region Require if (path == null) throw new ArgumentNullException(); if (string.IsNullOrEmpty(id) == true) throw new ArgumentNullException(); if (string.IsNullOrEmpty(name) == true) throw new ArgumentNullException(); #endregion _path = path; _id = id; _name = name; _childrenList = new List<DemoData>(); } // Member public string Path { get { return _path; } } public string Id { get { return _id; } } public string Name { get { return _name; } } public List<DemoData> ChildrenList { get { return _childrenList; } } } public class DemoDataObject : DemoData, IHierarchicalObject { // Properties private readonly string _parentPath; // Construction public DemoDataObject(string parentPath, DemoData demoData) : base(demoData.Path, demoData.Id, demoData.Name) { _parentPath = parentPath; foreach (DemoData childrenObject in demoData.ChildrenList) { this.ChildrenList.Add(childrenObject); } } // Member public string ParentPath { get { return _parentPath; } } } public class DemoDataObjectEnumerable : IEnumerable<DemoDataObject>, IEnumerable<IHierarchicalObject> { // Properties private readonly string _parentPath; private readonly IEnumerable<DemoData> _demoDataEnumerable; // Construction public DemoDataObjectEnumerable(IEnumerable<DemoData> demoDataEnumerable) : this(null, demoDataEnumerable) { } public DemoDataObjectEnumerable(string parentPath, IEnumerable<DemoData> demoDataEnumerable) { Require#region Require if (demoDataEnumerable == null) throw new ArgumentNullException(); #endregion _parentPath = parentPath; _demoDataEnumerable = demoDataEnumerable; } // Member public IEnumerator<DemoDataObject> GetEnumerator() { return new DemoDataObjectEnumerator(_parentPath, _demoDataEnumerable.GetEnumerator()); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } IEnumerator<IHierarchicalObject> IEnumerable<IHierarchicalObject>.GetEnumerator() { return (IEnumerator<IHierarchicalObject>)this.GetEnumerator(); } } public class DemoDataObjectEnumerator : IEnumerator<DemoDataObject>, IEnumerator<IHierarchicalObject> { // Properties private readonly string _parentPath; private readonly IEnumerator<DemoData> _demoDataEnumerator; private DemoDataObject _currentObject = null; private IEnumerator<DemoDataObject> _currentChildrenEnumerator = null; // Construction public DemoDataObjectEnumerator(string parentPath, IEnumerator<DemoData> demoDataEnumerator) { Require#region Require if (demoDataEnumerator == null) throw new ArgumentNullException(); #endregion _parentPath = parentPath; _demoDataEnumerator = demoDataEnumerator; } public void Dispose() { } // Member public DemoDataObject Current { get { return _currentObject; } } object System.Collections.IEnumerator.Current { get { return this.Current; } } IHierarchicalObject IEnumerator<IHierarchicalObject>.Current { get { return this.Current; } } public bool MoveNext() { if (_currentObject != null) { if (_currentChildrenEnumerator.MoveNext() == true) { _currentObject = _currentChildrenEnumerator.Current; return true; } } if (_demoDataEnumerator.MoveNext() == true) { _currentObject = new DemoDataObject(_parentPath, _demoDataEnumerator.Current); _currentChildrenEnumerator = new DemoDataObjectEnumerator(_currentObject.Path, _currentObject.ChildrenList.GetEnumerator()); return true; } _currentObject = null; _currentChildrenEnumerator = null; return false; } public void Reset() { _demoDataEnumerator.Reset(); _currentObject = null; _currentChildrenEnumerator = null; } } } }
DataTable资料系结 :
DataTable数据系结,主要是使用Adapter这个Pattern来将DataSet数据做转接处理。
namespace WebApplication1 { public partial class WebForm2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (this.IsPostBack == false) { DataTable demoDataTable = this.CreateDemoDataTable(); IEnumerable<IHierarchicalObject> demoDataObjectEnumerable = new DemoDataObjectEnumerable(demoDataTable); GridView1.DataSource = CreateDemoDataTable(); GridView1.DataBind(); TreeView1.DataSource = new HierarchicalObjectDataSource(demoDataObjectEnumerable); TreeView1.DataBind(); } } private DataTable CreateDemoDataTable() { DataRow dataRow; DataTable demoDataTable = new DataTable(); demoDataTable.Columns.Add("ParentPath", typeof(string)); demoDataTable.Columns.Add("Path", typeof(string)); demoDataTable.Columns.Add("Id", typeof(string)); demoDataTable.Columns.Add("Name", typeof(string)); dataRow = demoDataTable.NewRow(); dataRow["ParentPath"] = null; dataRow["Path"] = "AAA"; dataRow["Id"] = "Id_AAA"; dataRow["Name"] = "Name_AAA"; demoDataTable.Rows.Add(dataRow); dataRow = demoDataTable.NewRow(); dataRow["ParentPath"] = null; dataRow["Path"] = "BBB"; dataRow["Id"] = "Id_BBB"; dataRow["Name"] = "Name_BBB"; demoDataTable.Rows.Add(dataRow); dataRow = demoDataTable.NewRow(); dataRow["ParentPath"] = null; dataRow["Path"] = "CCC"; dataRow["Id"] = "Id_CCC"; dataRow["Name"] = "Name_CCC"; demoDataTable.Rows.Add(dataRow); dataRow = demoDataTable.NewRow(); dataRow["ParentPath"] = "BBB"; dataRow["Path"] = "DDD"; dataRow["Id"] = "Id_DDD"; dataRow["Name"] = "Name_DDD"; demoDataTable.Rows.Add(dataRow); dataRow = demoDataTable.NewRow(); dataRow["ParentPath"] = "DDD"; dataRow["Path"] = "EEE"; dataRow["Id"] = "Id_EEE"; dataRow["Name"] = "Name_EEE"; demoDataTable.Rows.Add(dataRow); return demoDataTable; } public class DemoDataObject : IHierarchicalObject { // Properties private readonly DataRow _dataRow; // Construction public DemoDataObject(DataRow dataRow) { Require#region Require if (dataRow == null) throw new ArgumentNullException(); #endregion _dataRow = dataRow; } // Member public string ParentPath { get { return _dataRow["ParentPath"] as string; } } public string Path { get { return _dataRow["Path"] as string; } } public string Id { get { return _dataRow["Id"] as string; } } public string Name { get { return _dataRow["Name"] as string; } } } public class DemoDataObjectEnumerable : IEnumerable<DemoDataObject>, IEnumerable<IHierarchicalObject> { // Properties private readonly DataTable _demoDataTable; // Construction public DemoDataObjectEnumerable(DataTable demoDataTable) { Require#region Require if (demoDataTable == null) throw new ArgumentNullException(); #endregion _demoDataTable = demoDataTable; } // Member public IEnumerator<DemoDataObject> GetEnumerator() { return new DemoDataObjectEnumerator(_demoDataTable.Rows.GetEnumerator()); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } IEnumerator<IHierarchicalObject> IEnumerable<IHierarchicalObject>.GetEnumerator() { return (IEnumerator<IHierarchicalObject>)this.GetEnumerator(); } } public class DemoDataObjectEnumerator : IEnumerator<DemoDataObject>, IEnumerator<IHierarchicalObject> { // Properties private readonly IEnumerator _dataRowEnumerator; private DemoDataObject _currentObject = null; // Construction public DemoDataObjectEnumerator(IEnumerator dataRowEnumerator) { Require#region Require if (dataRowEnumerator == null) throw new ArgumentNullException(); #endregion _dataRowEnumerator = dataRowEnumerator; } public void Dispose() { } // Member public DemoDataObject Current { get { return _currentObject; } } object System.Collections.IEnumerator.Current { get { return this.Current; } } IHierarchicalObject IEnumerator<IHierarchicalObject>.Current { get { return this.Current; } } public bool MoveNext() { if (_dataRowEnumerator.MoveNext() == true) { _currentObject = new DemoDataObject(_dataRowEnumerator.Current as DataRow); return true; } _currentObject = null; return false; } public void Reset() { _dataRowEnumerator.Reset(); } } } }