EAElement.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. namespace SAGA.DotNetUtils.Data
  6. {
  7. /// <summary>
  8. /// 基础节点元素
  9. /// </summary>
  10. public class EAElement<T> where T : EAElement<T>
  11. {
  12. public EAElement()
  13. {
  14. Children = new EAElementCollection<T>(this as T);
  15. }
  16. /// <summary>
  17. /// 节点Id
  18. /// </summary>
  19. public string Id { get; internal set; }
  20. /// <summary>
  21. /// 节点名称
  22. /// </summary>
  23. public string Name { get; set; }
  24. /// <summary>
  25. /// 关联相关元素
  26. /// </summary>
  27. public object Tag { get; set; }
  28. #region 父子关联元素处理
  29. public EAElementCollection<T> Children { get; private set; }
  30. public T Parent { get; internal set; }
  31. #endregion
  32. #region 公开方法
  33. /// <summary>
  34. /// 获取根节点
  35. /// </summary>
  36. /// <returns></returns>
  37. public T GetRoot()
  38. {
  39. T root = this as T;
  40. if (root == null)
  41. return root;
  42. while ((root.Parent) != null)
  43. {
  44. root = root.Parent;
  45. }
  46. return root;
  47. }
  48. /// <summary>
  49. /// 节点深度
  50. /// </summary>
  51. public int Deep
  52. {
  53. get
  54. {
  55. int deep = 1;
  56. T root = this as T;
  57. if (root == null)
  58. return deep;
  59. while ((root.Parent) != null)
  60. {
  61. root = root.Parent;
  62. deep++;
  63. }
  64. return deep;
  65. }
  66. }
  67. /// <summary>
  68. /// 获取所有的叶子节点
  69. /// </summary>
  70. /// <returns></returns>
  71. public List<T> GetLeaves()
  72. {
  73. List<T> result = new List<T>();
  74. Queue<T> queue = new Queue<T>();
  75. queue.Enqueue(this as T);
  76. while (queue.Any())
  77. {
  78. var current = queue.Dequeue();
  79. if (current != null)
  80. {
  81. if (current.Children.Count == 0)
  82. {
  83. result.Add(current);
  84. }
  85. else
  86. {
  87. current.Children.ToList().ForEach(c => queue.Enqueue(c));
  88. }
  89. }
  90. }
  91. return result;
  92. }
  93. #endregion
  94. /// <summary>
  95. /// 有效的Id
  96. /// </summary>
  97. public bool ValidId
  98. {
  99. get { return !string.IsNullOrWhiteSpace(Id); }
  100. }
  101. /// <summary>
  102. /// 两个对象是否匹配
  103. /// </summary>
  104. /// <param name="ea"></param>
  105. /// <returns></returns>
  106. public virtual bool IsMatch(EAElement<T> ea)
  107. {
  108. if (ea == null || !ValidId)
  109. {
  110. return false;
  111. }
  112. return Id == ea.Id || this.Equals(ea);
  113. }
  114. #region 扩展数据相关
  115. protected Dictionary<string, object> m_DicRef = new Dictionary<string, object>();
  116. /// <summary>
  117. /// 注册关联值
  118. /// </summary>
  119. public void Set<V>(string key, V refObject)
  120. {
  121. m_DicRef[key] = refObject;
  122. }
  123. /// <summary>
  124. /// 获取关联对象
  125. /// </summary>
  126. /// <typeparam name="V"></typeparam>
  127. /// <param name="key"></param>
  128. /// <returns></returns>
  129. public V Get<V>(string key)
  130. {
  131. if (!m_DicRef.ContainsKey(key))
  132. return default(V);
  133. return (V) m_DicRef[key];
  134. }
  135. #endregion
  136. }
  137. #region 节点集合类
  138. /// <summary>
  139. /// 节点子项目集合类
  140. /// </summary>
  141. /// <typeparam name="T"></typeparam>
  142. public class EAElementCollection<T> : ObservableCollection<T> where T : EAElement<T>
  143. {
  144. private T m_Parent;
  145. internal EAElementCollection(T parent)
  146. {
  147. m_Parent = parent;
  148. }
  149. protected override void ClearItems()
  150. {
  151. foreach (var item in this)
  152. {
  153. if (item != null)
  154. {
  155. item.Parent = null;
  156. }
  157. }
  158. base.ClearItems();
  159. }
  160. protected override void InsertItem(int index, T item)
  161. {
  162. base.InsertItem(index, item);
  163. item.Parent = m_Parent;
  164. }
  165. protected override void RemoveItem(int index)
  166. {
  167. if (this[index] != null)
  168. {
  169. this[index].Parent = null;
  170. }
  171. base.RemoveItem(index);
  172. }
  173. protected override void SetItem(int index, T item)
  174. {
  175. base.SetItem(index, item);
  176. item.Parent = m_Parent;
  177. }
  178. public void AddRange(IEnumerable<T> items)
  179. {
  180. foreach (var item in items)
  181. {
  182. this.Add(item);
  183. }
  184. }
  185. public void Reverse()
  186. {
  187. var list = this.Items as List<T>;
  188. list?.Reverse();
  189. }
  190. }
  191. #endregion
  192. }