CoreTreeNodes.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7. namespace InABox.Core
  8. {
  9. public interface ICoreTreeNode
  10. {
  11. object? ID { get; set; }
  12. object? Parent { get; set; }
  13. object? Image { get; set; }
  14. CoreRow? Row { get; set; }
  15. object? this[string column] { get; set; }
  16. string Number { get; }
  17. }
  18. public class CoreTreeNode<TKey> : INotifyPropertyChanged, ICoreTreeNode
  19. {
  20. private CoreTreeNodes<TKey> _owner;
  21. public ObservableCollection<CoreTreeNode<TKey>> Children => new ObservableCollection<CoreTreeNode<TKey>>(_owner.GetChildrenOfParent(_id));
  22. object? ICoreTreeNode.ID
  23. {
  24. get => ID;
  25. set => ID = (TKey)value!;
  26. }
  27. private TKey _id;
  28. public TKey ID
  29. {
  30. get { return _id; }
  31. set
  32. {
  33. _id = value;
  34. RaisedOnPropertyChanged("ID");
  35. }
  36. }
  37. object? ICoreTreeNode.Parent
  38. {
  39. get => Parent;
  40. set => Parent = (TKey)value!;
  41. }
  42. private TKey _parent;
  43. public TKey Parent
  44. {
  45. get { return _parent; }
  46. set
  47. {
  48. _parent = value;
  49. RaisedOnPropertyChanged("Parent");
  50. }
  51. }
  52. private object? _image;
  53. public object? Image
  54. {
  55. get => _image;
  56. set
  57. {
  58. _image = value;
  59. RaisedOnPropertyChanged("Image");
  60. }
  61. }
  62. private CoreRow _row;
  63. public CoreRow Row
  64. {
  65. get => _row;
  66. set
  67. {
  68. _row = value;
  69. RaisedOnPropertyChanged("Row");
  70. RaisedOnPropertyChanged("Item[]");
  71. }
  72. }
  73. public object? this[string column]
  74. {
  75. get => Row[column];
  76. set
  77. {
  78. Row[column] = value;
  79. _owner.DoColumnChanged(this, column);
  80. }
  81. }
  82. public event PropertyChangedEventHandler? PropertyChanged;
  83. public void RaisedOnPropertyChanged(string propertyName)
  84. {
  85. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  86. }
  87. public CoreTreeNode(CoreTreeNodes<TKey> owner, CoreRow row)
  88. {
  89. _owner = owner;
  90. _row = row;
  91. }
  92. public CoreTreeNode(CoreTreeNodes<TKey> owner, TKey id, TKey parent, CoreRow row) : this(owner, row)
  93. {
  94. _id = id;
  95. _parent = parent;
  96. }
  97. public CoreTreeNode<TKey>? GetParent() => _owner[_parent];
  98. public int Index()
  99. {
  100. var parent = GetParent();
  101. return parent != null
  102. ? parent.Children.IndexOf(this) + 1
  103. : _owner.Nodes.IndexOf(this) + 1;
  104. }
  105. public void InvalidateData()
  106. {
  107. RaisedOnPropertyChanged("Row");
  108. RaisedOnPropertyChanged("Item[]");
  109. }
  110. public String Number
  111. {
  112. get
  113. {
  114. String result = Index().ToString();
  115. var parent = GetParent();
  116. while (parent != null)
  117. {
  118. int index = parent.Index();
  119. result = $"{index}.{result}";
  120. parent = parent.GetParent();
  121. }
  122. return result;
  123. }
  124. }
  125. }
  126. public class CoreTreeNodes<TKey>
  127. {
  128. private List<CoreTreeNode<TKey>> _nodes;
  129. private Dictionary<TKey, CoreTreeNode<TKey>> _nodeMap;
  130. public TKey DefaultKey { get; set; }
  131. public ObservableCollection<CoreTreeNode<TKey>> Nodes { get; } = new ObservableCollection<CoreTreeNode<TKey>>();
  132. public CoreTreeNode<TKey>? this[TKey id] => _nodeMap.GetValueOrDefault(id);
  133. public CoreTreeNodes(TKey defaultKey)
  134. {
  135. _nodes = new List<CoreTreeNode<TKey>>();
  136. _nodeMap = new Dictionary<TKey, CoreTreeNode<TKey>>();
  137. DefaultKey = defaultKey;
  138. }
  139. public CoreTreeNode<TKey> Add(TKey id, TKey parent, CoreRow row)
  140. {
  141. var node = new CoreTreeNode<TKey>(this, id, parent, row);
  142. _nodes.Add(node);
  143. _nodeMap[id] = node;
  144. if(Equals(node.Parent, DefaultKey))
  145. {
  146. Nodes.Add(node);
  147. }
  148. return node;
  149. }
  150. public void Clear()
  151. {
  152. _nodes.Clear();
  153. _nodeMap.Clear();
  154. Nodes.Clear();
  155. }
  156. public CoreTreeNode<TKey> Find(TKey id) => _nodeMap.GetValueOrDefault(id);
  157. public CoreTreeNode<TKey>? Find(CoreRow row) => _nodes.FirstOrDefault(x => x.Row == row);
  158. /// <summary>
  159. /// Gets a given node and recursively all its children given by <paramref name="id"/>.
  160. /// </summary>
  161. /// <param name="id"></param>
  162. /// <returns></returns>
  163. public IEnumerable<CoreTreeNode<TKey>> GetChildren(TKey id)
  164. {
  165. if(!_nodeMap.TryGetValue(id, out var node))
  166. {
  167. yield break;
  168. }
  169. yield return node;
  170. var children = GetChildrenOfParent(id);
  171. foreach (var child in children)
  172. foreach (var item in GetChildren(child.ID))
  173. yield return item;
  174. }
  175. /// <summary>
  176. /// Get all the direct children of the parent given by <paramref name="id"/>.
  177. /// </summary>
  178. /// <param name="id"></param>
  179. /// <returns></returns>
  180. public IEnumerable<CoreTreeNode<TKey>> GetChildrenOfParent(TKey id)
  181. {
  182. return _nodes.Where(x => object.Equals(x.Parent, id) && !object.Equals(x.ID, id));
  183. }
  184. public void Load<T>(CoreTable table, Expression<Func<T, TKey>> id, Expression<Func<T, TKey>> parentid)
  185. {
  186. _nodes.Clear();
  187. foreach (var row in table.Rows)
  188. {
  189. var _id = row.Get(id);
  190. var _parent = row.Get(parentid);
  191. Add(_id, _parent, row);
  192. }
  193. }
  194. public delegate void ColumnChangedEventHandler(CoreTreeNode<TKey> node, string column);
  195. public event ColumnChangedEventHandler? ColumnChanged;
  196. internal void DoColumnChanged(CoreTreeNode<TKey> node, string column)
  197. {
  198. ColumnChanged?.Invoke(node, column);
  199. }
  200. }
  201. }