TreeNodeBase.cs 3.4 KB
using System;
using System.Collections.Generic;

namespace Quiz.Utility
{
	/// <summary>
	/// 提供树结构对象类型的实现。
	/// </summary>
	public interface ITreeNodeBase
	{
		/// <summary>
		/// 键值,忽略大小写。
		/// </summary>
		string Key { get; set; }
		/// <summary>
		/// 父节点
		/// </summary>
		ITreeNodeBase Parent { get; set; }
		/// <summary>
		/// 子节点集合
		/// </summary>
		TreeNodeCollectionBase Children { get; set; }
	}

	/// <summary>
	/// 表示一个树节点集合。
	/// </summary>
	[Serializable]
	public class TreeNodeCollectionBase : System.Collections.ArrayList
	{
		/// <summary>
		/// 在当前的节点集合中(包括子节点)查找对应键值节点。
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public ITreeNodeBase FindNodeByKey(string key)
		{
			ITreeNodeBase cn = null;
			FindNodeByKey(key, this, ref cn);
			return cn;
		}

		/// <summary>
		/// 获取下一个需要生成的编码
		/// </summary>
		/// <returns></returns>
		public string NextCode()
		{
			List<string> keylist = new List<string>();

			foreach (ITreeNodeBase ctnb in this)
			{
				if (ctnb == null) continue;
				keylist.Add(ctnb.Key);
			}

			if (keylist.Count <= 0) return string.Empty;

			keylist.Sort();
			return Helper.IncreaseChar36(keylist[keylist.Count - 1]);
		}

		void FindNodeByKey(string findkey, TreeNodeCollectionBase findtag, ref ITreeNodeBase founddnode)
		{
			if (string.IsNullOrEmpty(findkey) || founddnode != null || findtag == null || findtag.Count <= 0) return;
			foreach (ITreeNodeBase node in findtag)
			{
				if (findkey.Equals(node.Key, StringComparison.CurrentCultureIgnoreCase)) { founddnode = node; return; }
				else FindNodeByKey(findkey, node.Children, ref founddnode);
				if (founddnode != null) return;
			}
		}

		/// <summary>
		/// 根据指定的节点索引列,将表数据格式化成指定对象类型的树结构状态。
		/// </summary>
		/// <param name="keycolumnname">进行编码分析的表的列名。</param>
		/// <param name="nodetype">将表的行数据转换成的对象类型。</param>
		/// <param name="datatable">表数据。</param>
		/// <returns></returns>
		public static TreeNodeCollectionBase FormatFromTable(string keycolumnname, Type nodetype, System.Data.DataTable datatable)
		{
			if (datatable == null || datatable.Rows.Count <= 0) return null;
			if (string.IsNullOrEmpty(keycolumnname)) throw new Exception();
			TreeNodeCollectionBase rootcol = new TreeNodeCollectionBase();
			System.Data.DataView view = datatable.DefaultView;
			view.Sort = keycolumnname;
			ITreeNodeBase lastnode = null;
			for (int i = 0; i < view.Count; i++)
			{
				if (view[i][keycolumnname] == DBNull.Value || view[i][keycolumnname] == null) continue;
				string key = view[i][keycolumnname].ToString();

				ITreeNodeBase parent = GetParentNode(key, lastnode);
				lastnode = ModelConstructor.CreateModel(nodetype, view[i]) as ITreeNodeBase;
				lastnode.Children = new TreeNodeCollectionBase();
				lastnode.Key = key; lastnode.Parent = parent;
				if (parent == null) rootcol.Add(lastnode);
				else parent.Children.Add(lastnode);
			}
			view.Dispose(); datatable.Dispose();

			return rootcol;
		}
		static ITreeNodeBase GetParentNode(string key, ITreeNodeBase lastnode)
		{
			if (lastnode == null) return null;
			if (key.IndexOf(lastnode.Key) == 0) return lastnode;
			else return GetParentNode(key, lastnode.Parent);
		}
	}
}