TreeViewModel.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel.Composition;
  5. using Microsoft.Practices.Prism.Mvvm;
  6. namespace Modules.BehaviorTreeModule
  7. {
  8. [Export(typeof (TreeViewModel)), PartCreationPolicy(CreationPolicy.NonShared)]
  9. public class TreeViewModel: BindableBase, ICloneable
  10. {
  11. private readonly ObservableCollection<TreeNodeViewModel> treeNodes =
  12. new ObservableCollection<TreeNodeViewModel>();
  13. private readonly Dictionary<int, TreeNodeViewModel> treeNodeDict =
  14. new Dictionary<int, TreeNodeViewModel>();
  15. public ObservableCollection<TreeNodeViewModel> TreeNodes
  16. {
  17. get
  18. {
  19. return this.treeNodes;
  20. }
  21. }
  22. public int TreeId { get; private set; }
  23. public int copyId;
  24. public TreeViewModel(AllTreeViewModel allTreeViewModel)
  25. {
  26. this.AllTreeViewModel = allTreeViewModel;
  27. this.TreeId = ++this.AllTreeViewModel.MaxTreeId;
  28. TreeNodeViewModel treeNodeViewModel = new TreeNodeViewModel(this, 300, 100);
  29. this.treeNodes.Add(treeNodeViewModel);
  30. this.treeNodeDict[treeNodeViewModel.Id] = treeNodeViewModel;
  31. TreeLayout treeLayout = new TreeLayout(this);
  32. treeLayout.ExcuteLayout();
  33. }
  34. public TreeViewModel(AllTreeViewModel allTreeViewModel, List<TreeNodeData> treeNodeDatas)
  35. {
  36. this.AllTreeViewModel = allTreeViewModel;
  37. this.TreeId = treeNodeDatas[0].TreeId;
  38. foreach (TreeNodeData treeNodeData in treeNodeDatas)
  39. {
  40. TreeNodeViewModel treeNodeViewModel = new TreeNodeViewModel(this, treeNodeData);
  41. this.treeNodes.Add(treeNodeViewModel);
  42. this.treeNodeDict[treeNodeViewModel.Id] = treeNodeViewModel;
  43. }
  44. TreeLayout treeLayout = new TreeLayout(this);
  45. treeLayout.ExcuteLayout();
  46. }
  47. public List<TreeNodeData> GetDatas()
  48. {
  49. var treeNodeDatas = new List<TreeNodeData>();
  50. foreach (TreeNodeViewModel treeNodeViewModel in this.treeNodes)
  51. {
  52. TreeNodeData treeNodeData = (TreeNodeData) treeNodeViewModel.Data.Clone();
  53. treeNodeDatas.Add(treeNodeData);
  54. }
  55. return treeNodeDatas;
  56. }
  57. public AllTreeViewModel AllTreeViewModel { get; private set; }
  58. public TreeNodeViewModel Root
  59. {
  60. get
  61. {
  62. return this.treeNodes.Count == 0? null : this.treeNodes[0];
  63. }
  64. }
  65. public TreeNodeViewModel Get(int id)
  66. {
  67. TreeNodeViewModel node;
  68. this.treeNodeDict.TryGetValue(id, out node);
  69. return node;
  70. }
  71. public void Add(TreeNodeViewModel treeNode, TreeNodeViewModel parent)
  72. {
  73. // 如果父节点是折叠的,需要先展开父节点
  74. if (parent != null && parent.IsFold)
  75. {
  76. this.UnFold(parent);
  77. }
  78. this.treeNodes.Add(treeNode);
  79. this.treeNodeDict[treeNode.Id] = treeNode;
  80. if (parent != null)
  81. {
  82. treeNode.Parent = parent;
  83. parent.Children.Add(treeNode.Id);
  84. }
  85. TreeLayout treeLayout = new TreeLayout(this);
  86. treeLayout.ExcuteLayout();
  87. }
  88. private void GetChildrenIdAndSelf(TreeNodeViewModel treeNodeViewModel, List<int> children)
  89. {
  90. children.Add(treeNodeViewModel.Id);
  91. this.GetAllChildrenId(treeNodeViewModel, children);
  92. }
  93. private void GetAllChildrenId(TreeNodeViewModel treeNodeViewModel, List<int> children)
  94. {
  95. foreach (int childId in treeNodeViewModel.Children)
  96. {
  97. TreeNodeViewModel child = this.Get(childId);
  98. children.Add(child.Id);
  99. this.GetAllChildrenId(child, children);
  100. }
  101. }
  102. public void Remove(TreeNodeViewModel treeNodeViewModel)
  103. {
  104. var allId = new List<int>();
  105. this.GetChildrenIdAndSelf(treeNodeViewModel, allId);
  106. foreach (int childId in allId)
  107. {
  108. TreeNodeViewModel child = this.Get(childId);
  109. this.treeNodes.Remove(child);
  110. this.treeNodes.Remove(treeNodeViewModel);
  111. }
  112. TreeNodeViewModel parent = treeNodeViewModel.Parent;
  113. if (parent != null)
  114. {
  115. parent.Children.Remove(treeNodeViewModel.Id);
  116. }
  117. TreeLayout treeLayout = new TreeLayout(this);
  118. treeLayout.ExcuteLayout();
  119. }
  120. private void RecursionMove(TreeNodeViewModel treeNodeViewModel, double offsetX, double offsetY)
  121. {
  122. treeNodeViewModel.X += offsetX;
  123. treeNodeViewModel.Y += offsetY;
  124. foreach (int childId in treeNodeViewModel.Children)
  125. {
  126. TreeNodeViewModel child = this.Get(childId);
  127. this.RecursionMove(child, offsetX, offsetY);
  128. }
  129. }
  130. public void MoveToPosition(double offsetX, double offsetY)
  131. {
  132. this.RecursionMove(this.Root, offsetX, offsetY);
  133. }
  134. public void MoveToNode(TreeNodeViewModel from, TreeNodeViewModel to)
  135. {
  136. // from节点不能是to节点的父级节点
  137. TreeNodeViewModel tmpNode = to;
  138. while (tmpNode != null)
  139. {
  140. if (tmpNode.IsRoot)
  141. {
  142. break;
  143. }
  144. if (tmpNode.Id == from.Id)
  145. {
  146. return;
  147. }
  148. tmpNode = tmpNode.Parent;
  149. }
  150. if (from.IsFold)
  151. {
  152. this.UnFold(from);
  153. }
  154. if (to.IsFold)
  155. {
  156. this.UnFold(to);
  157. }
  158. from.Parent.Children.Remove(from.Id);
  159. to.Children.Add(from.Id);
  160. from.Parent = to;
  161. TreeLayout treeLayout = new TreeLayout(this);
  162. treeLayout.ExcuteLayout();
  163. }
  164. /// <summary>
  165. /// 折叠节点
  166. /// </summary>
  167. /// <param name="treeNodeViewModel"></param>
  168. public void Fold(TreeNodeViewModel treeNodeViewModel)
  169. {
  170. var allChildId = new List<int>();
  171. this.GetAllChildrenId(treeNodeViewModel, allChildId);
  172. foreach (int childId in allChildId)
  173. {
  174. TreeNodeViewModel child = this.Get(childId);
  175. this.treeNodes.Remove(child);
  176. }
  177. treeNodeViewModel.IsFold = true;
  178. TreeLayout treeLayout = new TreeLayout(this);
  179. treeLayout.ExcuteLayout();
  180. }
  181. /// <summary>
  182. /// 展开节点,一级一级展开,一次只展开下层子节点,比如下层节点是折叠的,那下下层节点不展开
  183. /// </summary>
  184. /// <param name="treeNodeViewModel"></param>
  185. public void UnFold(TreeNodeViewModel treeNodeViewModel)
  186. {
  187. treeNodeViewModel.IsFold = false;
  188. var allChildId = new List<int>();
  189. this.GetAllChildrenId(treeNodeViewModel, allChildId);
  190. foreach (int childId in allChildId)
  191. {
  192. TreeNodeViewModel child = this.Get(childId);
  193. this.treeNodes.Add(child);
  194. }
  195. TreeLayout treeLayout = new TreeLayout(this);
  196. treeLayout.ExcuteLayout();
  197. }
  198. public void MoveLeft(TreeNodeViewModel treeNodeViewModel)
  199. {
  200. if (treeNodeViewModel.IsRoot)
  201. {
  202. return;
  203. }
  204. TreeNodeViewModel parent = treeNodeViewModel.Parent;
  205. int index = parent.Children.IndexOf(treeNodeViewModel.Id);
  206. if (index == 0)
  207. {
  208. return;
  209. }
  210. parent.Children.Remove(treeNodeViewModel.Id);
  211. parent.Children.Insert(index - 1, treeNodeViewModel.Id);
  212. TreeLayout treeLayout = new TreeLayout(this);
  213. treeLayout.ExcuteLayout();
  214. }
  215. public void MoveRight(TreeNodeViewModel treeNodeViewModel)
  216. {
  217. if (treeNodeViewModel.IsRoot)
  218. {
  219. return;
  220. }
  221. TreeNodeViewModel parent = treeNodeViewModel.Parent;
  222. int index = parent.Children.IndexOf(treeNodeViewModel.Id);
  223. if (index == parent.Children.Count - 1)
  224. {
  225. return;
  226. }
  227. parent.Children.Remove(treeNodeViewModel.Id);
  228. parent.Children.Insert(index + 1, treeNodeViewModel.Id);
  229. TreeLayout treeLayout = new TreeLayout(this);
  230. treeLayout.ExcuteLayout();
  231. }
  232. public void Copy(TreeNodeViewModel copyTreeNodeViewModel)
  233. {
  234. this.copyId = copyTreeNodeViewModel.Id;
  235. }
  236. public void Paste(TreeNodeViewModel pasteTreeNodeViewModel)
  237. {
  238. if (this.copyId == 0)
  239. {
  240. return;
  241. }
  242. TreeNodeViewModel copyTreeNodeViewModel = this.treeNodeDict[this.copyId];
  243. // copy节点不能是paste节点的父级节点
  244. TreeNodeViewModel tmpNode = pasteTreeNodeViewModel;
  245. while (tmpNode != null)
  246. {
  247. if (tmpNode.IsRoot)
  248. {
  249. break;
  250. }
  251. if (tmpNode.Id == copyTreeNodeViewModel.Id)
  252. {
  253. return;
  254. }
  255. tmpNode = tmpNode.Parent;
  256. }
  257. this.copyId = 0;
  258. this.CopyTree(copyTreeNodeViewModel, pasteTreeNodeViewModel);
  259. }
  260. private void CopyTree(TreeNodeViewModel copyTreeNodeViewModel, TreeNodeViewModel parent)
  261. {
  262. TreeNodeData newTreeNodeData = (TreeNodeData) copyTreeNodeViewModel.Data.Clone();
  263. newTreeNodeData.Id = ++this.AllTreeViewModel.MaxNodeId;
  264. newTreeNodeData.TreeId = this.TreeId;
  265. newTreeNodeData.Children.Clear();
  266. TreeNodeViewModel newTreeNodeViewModel = new TreeNodeViewModel(this, newTreeNodeData);
  267. this.Add(newTreeNodeViewModel, parent);
  268. foreach (int childId in copyTreeNodeViewModel.Children)
  269. {
  270. TreeNodeViewModel child = this.Get(childId);
  271. this.CopyTree(child, newTreeNodeViewModel);
  272. }
  273. }
  274. public object Clone()
  275. {
  276. int treeId = ++this.AllTreeViewModel.MaxTreeId;
  277. List<TreeNodeData> treeNodeDatas = this.GetDatas();
  278. // 旧id和新id的映射关系
  279. var idMapping = new Dictionary<int, int>();
  280. idMapping[0] = 0;
  281. foreach (TreeNodeData treeNodeData in treeNodeDatas)
  282. {
  283. int newId = ++this.AllTreeViewModel.MaxNodeId;
  284. idMapping[treeNodeData.Id] = newId;
  285. treeNodeData.Id = newId;
  286. treeNodeData.TreeId = treeId;
  287. }
  288. foreach (TreeNodeData treeNodeData in treeNodeDatas)
  289. {
  290. treeNodeData.Parent = idMapping[treeNodeData.Parent];
  291. for (int i = 0; i < treeNodeData.Children.Count; ++i)
  292. {
  293. treeNodeData.Children[i] = idMapping[treeNodeData.Children[i]];
  294. }
  295. }
  296. TreeViewModel clone = new TreeViewModel(this.AllTreeViewModel, treeNodeDatas);
  297. return clone;
  298. }
  299. }
  300. }