终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

903 lines
30 KiB

  1. using BeDesignerSCADA.Adorners;
  2. using BeDesignerSCADA.Speical;
  3. using BPASmartClient.Compiler;
  4. using BPASmartClient.SCADAControl;
  5. using Microsoft.Toolkit.Mvvm.Input;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Reflection;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using System.Windows;
  15. using System.Windows.Controls;
  16. using System.Windows.Controls.Primitives;
  17. using System.Windows.Documents;
  18. using System.Windows.Input;
  19. using System.Windows.Markup;
  20. using System.Windows.Media;
  21. using System.Windows.Shapes;
  22. using System.Xml;
  23. namespace BeDesignerSCADA.Controls
  24. {
  25. public class CanvasPanel : Canvas
  26. {
  27. public CanvasPanel()
  28. {
  29. UseLayoutRounding = true;
  30. Drop += CanvasPanel_Drop;
  31. CopySelectItemsCommand = new RelayCommand(CopySelectItems);
  32. PasteSelectItemsCommand = new RelayCommand(PasteSelectItems);
  33. DeleteSelectItemsCommand = new RelayCommand(DeleteSelectItems);
  34. SetTopLayerCommand = new RelayCommand(SetTopLayer);
  35. SetBottomLayerCommand = new RelayCommand(SetBottomLayer);
  36. SelectedItems = new ObservableCollection<FrameworkElement>();
  37. //ResourceDictionary resourceDictionary = new ResourceDictionary();
  38. //Application.LoadComponent(resourceDictionary, new Uri("/BeDesignerSCADA;component/Themes/Styles.xaml", UriKind.Relative));
  39. //ContextMenu = resourceDictionary.FindName("CanvasRightMenu") as ContextMenu;
  40. ContextMenu=Application.Current.Resources["CanvasRightMenu"] as ContextMenu;
  41. KeyDown += CanvasPanel_KeyDown;
  42. }
  43. #region 添加控件
  44. private void CanvasPanel_Drop(object sender, DragEventArgs e)
  45. {
  46. Type type = e.Data.GetData("System.RuntimeType") as Type;
  47. var t = type.GetCustomAttributes(typeof(ControlTypeAttribute), false);
  48. if (t.Length > 0)
  49. {
  50. Console.WriteLine((t as ControlTypeAttribute[])[0].Group);
  51. }
  52. try
  53. {
  54. var control = Activator.CreateInstance(type) as FrameworkElement;
  55. control.Name = GetControlName(type);
  56. Children.Add(control);
  57. var xPos = e.GetPosition(this).X;
  58. var yPos = e.GetPosition(this).Y;
  59. if (xPos % GridPxiel != 0)
  60. xPos = (GridPxiel - xPos % GridPxiel) + xPos;
  61. if (yPos % GridPxiel != 0)
  62. yPos = (GridPxiel - yPos % GridPxiel) + yPos;
  63. SetLeft(control, xPos);
  64. SetTop(control, yPos);
  65. SelectedItems = new ObservableCollection<FrameworkElement>() { control };
  66. SelectedItem = control;
  67. }
  68. catch (Exception)
  69. {
  70. }
  71. }
  72. string GetControlName(Type ctrlType)
  73. {
  74. var children = Children.GetEnumerator();
  75. children.Reset();
  76. List<string> names = new List<string>();
  77. while (children.MoveNext())
  78. {
  79. if (children.Current.GetType().Name == ctrlType.Name)
  80. {
  81. names.Add((children.Current as FrameworkElement).Name);
  82. }
  83. }
  84. var nameIndex = names.Count;
  85. while (names.Contains($"{ctrlType.Name.ToLower().Replace("the", string.Empty)}{nameIndex}"))
  86. {
  87. nameIndex++;
  88. }
  89. return $"{ctrlType.Name.ToLower().Replace("the", string.Empty)}{nameIndex}";
  90. }
  91. #endregion
  92. #region 初始化
  93. protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
  94. {
  95. if (visualAdded is Border || visualRemoved is Border)
  96. {
  97. return;
  98. }
  99. if (visualAdded is FrameworkElement ctrl)
  100. {
  101. ctrl.PreviewMouseLeftButtonDown += Ctrl_MouseLeftButtonDown;
  102. }
  103. if (visualRemoved is FrameworkElement ctr)
  104. {
  105. ctr.PreviewMouseLeftButtonDown -= Ctrl_MouseLeftButtonDown;
  106. }
  107. base.OnVisualChildrenChanged(visualAdded, visualRemoved);
  108. }
  109. #endregion
  110. #region 单击选中项处理
  111. /// <summary>
  112. /// 单击了控件时:不调用框选的刷新方式
  113. /// </summary>
  114. bool isClickedControl = false;
  115. /// <summary>
  116. /// 左键按下
  117. /// </summary>
  118. /// <param name="sender"></param>
  119. /// <param name="e"></param>
  120. private void Ctrl_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
  121. {
  122. if (sender is FrameworkElement ctl)
  123. {
  124. var cp = GetParentObject<CanvasPanel>(ctl);
  125. if (Keyboard.Modifiers == ModifierKeys.Control)
  126. {
  127. cp.SelectedItems.Add(ctl);
  128. }
  129. else
  130. {
  131. cp.SelectedItems = new ObservableCollection<FrameworkElement>() { ctl };
  132. }
  133. isClickedControl = true;
  134. RefreshSelection();
  135. }
  136. }
  137. /// <summary>
  138. /// 获取属性
  139. /// </summary>
  140. /// <typeparam name="T"></typeparam>
  141. /// <param name="obj"></param>
  142. /// <returns></returns>
  143. public static T GetParentObject<T>(DependencyObject obj) where T : FrameworkElement
  144. {
  145. DependencyObject parent = VisualTreeHelper.GetParent(obj);
  146. while (parent != null)
  147. {
  148. if (parent is T)
  149. {
  150. return (T)parent;
  151. }
  152. parent = VisualTreeHelper.GetParent(parent);
  153. }
  154. return null;
  155. }
  156. #endregion
  157. #region 右键菜单
  158. #endregion
  159. #region 绘制选择框
  160. Border selectionBorder = new Border()
  161. {
  162. Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#557F7F7F")),
  163. BorderThickness = new Thickness(1),
  164. BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF303030")),
  165. };
  166. protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
  167. {
  168. base.OnMouseLeftButtonDown(e);
  169. selectionStart = e.GetPosition(this);
  170. if (!this.Children.Contains(selectionBorder))
  171. {
  172. this.Children.Add(selectionBorder);
  173. this.CaptureMouse();
  174. }
  175. }
  176. Point selectionStart = default;
  177. protected override void OnMouseMove(MouseEventArgs e)
  178. {
  179. if (isClickedControl)
  180. {
  181. return;
  182. }
  183. base.OnMouseMove(e);
  184. if (e.LeftButton == MouseButtonState.Pressed)
  185. {
  186. var nowPoint = e.GetPosition(this);
  187. var offsetX = nowPoint.X - selectionStart.X;
  188. var offsetY = nowPoint.Y - selectionStart.Y;
  189. Clear();
  190. selectionBorder.Width = Math.Abs(offsetX);
  191. selectionBorder.Height = Math.Abs(offsetY);
  192. // 分四种情况绘制
  193. if (offsetX >= 0 && offsetY >= 0)// 右下
  194. {
  195. SetLeft(selectionBorder, selectionStart.X);
  196. SetTop(selectionBorder, selectionStart.Y);
  197. }
  198. else if (offsetX > 0 && offsetY < 0)// 右上
  199. {
  200. SetLeft(selectionBorder, selectionStart.X);
  201. SetBottom(selectionBorder, ActualHeight - selectionStart.Y);
  202. }
  203. else if (offsetX < 0 && offsetY > 0)// 左下
  204. {
  205. SetRight(selectionBorder, ActualWidth - selectionStart.X);
  206. SetTop(selectionBorder, selectionStart.Y);
  207. }
  208. else if (offsetX < 0 && offsetY < 0)// 左上
  209. {
  210. SetRight(selectionBorder, ActualWidth - selectionStart.X);
  211. SetBottom(selectionBorder, ActualHeight - selectionStart.Y);
  212. }
  213. }
  214. }
  215. protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
  216. {
  217. base.OnMouseLeftButtonUp(e);
  218. if (double.IsNaN(GetLeft(selectionBorder)))
  219. {
  220. SetLeft(selectionBorder, ActualWidth - GetRight(selectionBorder) - selectionBorder.ActualWidth);
  221. }
  222. if (double.IsNaN(GetTop(selectionBorder)))
  223. {
  224. SetTop(selectionBorder, ActualHeight - GetBottom(selectionBorder) - selectionBorder.ActualHeight);
  225. }
  226. FrameSelection(GetLeft(selectionBorder), GetTop(selectionBorder), selectionBorder.Width, selectionBorder.Height);
  227. selectionBorder.Width = 0;
  228. selectionBorder.Height = 0;
  229. this.Children.Remove(selectionBorder);
  230. this.ReleaseMouseCapture();
  231. }
  232. private void Clear()
  233. {
  234. SetLeft(selectionBorder, double.NaN);
  235. SetRight(selectionBorder, double.NaN);
  236. SetTop(selectionBorder, double.NaN);
  237. SetBottom(selectionBorder, double.NaN);
  238. }
  239. #endregion
  240. #region 选中属性
  241. public FrameworkElement SelectedItem
  242. {
  243. get { return (FrameworkElement)GetValue(SelectedItemProperty); }
  244. set { SetValue(SelectedItemProperty, value); }
  245. }
  246. public static readonly DependencyProperty SelectedItemProperty =
  247. DependencyProperty.Register("SelectedItem", typeof(FrameworkElement), typeof(CanvasPanel), new PropertyMetadata(null, OnSelectedItemChanged));
  248. private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as CanvasPanel)?.RefreshSelection1();
  249. public void RefreshSelection1()
  250. {
  251. }
  252. #endregion
  253. #region 框选
  254. public ObservableCollection<FrameworkElement> SelectedItems
  255. {
  256. get { return (ObservableCollection<FrameworkElement>)GetValue(SelectedItemsProperty); }
  257. set { SetValue(SelectedItemsProperty, value); }
  258. }
  259. public static readonly DependencyProperty SelectedItemsProperty =
  260. DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<FrameworkElement>), typeof(CanvasPanel), new PropertyMetadata(null, OnSelectedItemsChanged));
  261. private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as CanvasPanel)?.RefreshSelection();
  262. public void RefreshSelection()
  263. {
  264. foreach (var item in Children)
  265. {
  266. if (!(item is IExecutable))
  267. continue;
  268. var ele = item as FrameworkElement;
  269. if (ele == null) continue;
  270. var layer = AdornerLayer.GetAdornerLayer(ele);
  271. var arr = layer.GetAdorners(ele);//获取该控件上所有装饰器,返回一个数组
  272. if (arr != null)
  273. {
  274. for (int i = arr.Length - 1; i >= 0; i--)
  275. {
  276. layer.Remove(arr[i]);
  277. }
  278. }
  279. }
  280. if (SelectedItems != null)
  281. {
  282. foreach (var item in SelectedItems)
  283. {
  284. var layer = AdornerLayer.GetAdornerLayer(item);
  285. layer.Add(new SelectionAdorner(item));
  286. SelectedItem = item;
  287. }
  288. }
  289. }
  290. /// <summary>
  291. /// 移除所有选择装饰器
  292. /// </summary>
  293. public void ClearSelection()
  294. {
  295. foreach (var item in Children)
  296. {
  297. if (!(item is IExecutable))
  298. continue;
  299. var ele = item as FrameworkElement;
  300. if (ele == null) continue;
  301. var layer = AdornerLayer.GetAdornerLayer(ele);
  302. var arr = layer.GetAdorners(ele);//获取该控件上所有装饰器,返回一个数组
  303. if (arr != null)
  304. {
  305. for (int i = arr.Length - 1; i >= 0; i--)
  306. {
  307. layer.Remove(arr[i]);
  308. }
  309. }
  310. }
  311. }
  312. /// <summary>
  313. /// 计算框选项
  314. /// </summary>
  315. private void FrameSelection(double x, double y, double width, double height)
  316. {
  317. if (width > 0 || height > 0)
  318. {
  319. isClickedControl = false;
  320. }
  321. if (isClickedControl)
  322. {
  323. isClickedControl = false;
  324. SelectedItems = new ObservableCollection<FrameworkElement>();
  325. return;
  326. }
  327. SelectedItems = new ObservableCollection<FrameworkElement>();
  328. foreach (var item in Children)
  329. {
  330. if (item is FrameworkElement ctrl && !(ctrl is Border))
  331. {
  332. // 框左上角
  333. var left = GetLeft(ctrl);
  334. var top = GetTop(ctrl);
  335. if (left >= x && left <= x + width && top >= y && top <= y + height)
  336. {
  337. if (!SelectedItems.Contains(ctrl))
  338. SelectedItems.Add(ctrl);
  339. }
  340. // 框右下角
  341. var right = left + ctrl.ActualWidth;
  342. var bottom = top + ctrl.ActualHeight;
  343. if (right >= x && right <= x + width && bottom >= y && bottom <= y + height)
  344. {
  345. if (!SelectedItems.Contains(ctrl))
  346. SelectedItems.Add(ctrl);
  347. }
  348. // 框右上角
  349. if (right >= x && right <= x + width && top >= y && top <= y + height)
  350. {
  351. if (!SelectedItems.Contains(ctrl))
  352. SelectedItems.Add(ctrl);
  353. }
  354. // 框左下角
  355. if (left >= x && left <= x + width && bottom >= y && bottom <= y + height)
  356. {
  357. if (!SelectedItems.Contains(ctrl))
  358. SelectedItems.Add(ctrl);
  359. }
  360. }
  361. }
  362. RefreshSelection();
  363. }
  364. #endregion
  365. #region 外部调用
  366. public List<FrameworkElement> GetAllExecChildren()
  367. {
  368. List<FrameworkElement> result = new List<FrameworkElement>();
  369. foreach (var ctrl in Children)
  370. {
  371. if (ctrl is IExecutable exec)
  372. {
  373. result.Add(ctrl as FrameworkElement);
  374. }
  375. }
  376. return result;
  377. }
  378. /// <summary>
  379. /// 对齐像素单位
  380. /// </summary>
  381. public int GridPxiel
  382. {
  383. get { return (int)GetValue(GridPxielProperty); }
  384. set { SetValue(GridPxielProperty, value); }
  385. }
  386. public static readonly DependencyProperty GridPxielProperty =
  387. DependencyProperty.Register("GridPxiel", typeof(int), typeof(CanvasPanel), new PropertyMetadata(4));
  388. public void MoveControls(double offsetX, double offsetY)
  389. {
  390. ClearAlignLine();
  391. // 获取可对齐的点
  392. List<Point> points = new List<Point>();
  393. foreach (FrameworkElement ctrl in Children)
  394. {
  395. if (!SelectedItems.Contains(ctrl))
  396. {
  397. // 左上的点
  398. Point item = new Point(GetLeft(ctrl), GetTop(ctrl));
  399. points.Add(item);
  400. // 左下的点
  401. Point itemlb = new Point(GetLeft(ctrl), GetTop(ctrl) + ctrl.ActualHeight);
  402. points.Add(itemlb);
  403. // 右下的点
  404. Point itemrb = new Point(GetLeft(ctrl) + ctrl.ActualWidth, GetTop(ctrl) + ctrl.ActualHeight);
  405. points.Add(itemrb);
  406. // 右上的点
  407. Point itemrt = new Point(GetLeft(ctrl) + ctrl.ActualWidth, GetTop(ctrl));
  408. points.Add(itemrt);
  409. }
  410. }
  411. // 控件移动
  412. foreach (var item in SelectedItems)
  413. {
  414. var moveX = GetLeft(item) + offsetX;
  415. moveX = (moveX < 0) ? 0 : moveX;
  416. var moveY = GetTop(item) + offsetY;
  417. moveY = moveY < 0 ? 0 : moveY;
  418. if (moveX % GridPxiel != 0)
  419. moveX = (GridPxiel - moveX % GridPxiel) + moveX;
  420. if (moveY % GridPxiel != 0)
  421. moveY = (GridPxiel - moveY % GridPxiel) + moveY;
  422. SetLeft(item, moveX);
  423. SetTop(item, moveY);
  424. }
  425. // 计算是否显示对齐线
  426. var targetItemTop = SelectedItems?.Min(x => GetTop(x));
  427. var targetItem = SelectedItems.FirstOrDefault(x => GetTop(x) == targetItemTop);
  428. var lefAlign = points.FirstOrDefault(x => Math.Abs(x.X - GetLeft(targetItem)) == 0);
  429. if (lefAlign != default)
  430. {
  431. //SetLeft(targetItem, lefAlign.X);
  432. var layer = AdornerLayer.GetAdornerLayer(this);
  433. layer.Add(new SelectionAlignLine(this, lefAlign, new Point(GetLeft(targetItem), GetTop(targetItem))));
  434. }
  435. var topAlign = points.FirstOrDefault(x => Math.Abs(x.Y - GetTop(targetItem)) == 0);
  436. if (topAlign != default)
  437. {
  438. //SetTop(targetItem, topAlign.Y);
  439. var layer = AdornerLayer.GetAdornerLayer(this);
  440. layer.Add(new SelectionAlignLine(this, topAlign, new Point(GetLeft(targetItem), GetTop(targetItem))));
  441. }
  442. int px = 20;
  443. // 网格对齐
  444. if (UseAutoAlignment)
  445. {
  446. foreach (var item in SelectedItems)
  447. {
  448. var left = GetLeft(item);
  449. if (left % px <= 1)
  450. {
  451. SetLeft(item, (int)left / px * px);
  452. }
  453. var top = GetTop(item);
  454. if (top % px <= 1)
  455. {
  456. SetTop(item, (int)top / px * px);
  457. }
  458. }
  459. }
  460. }
  461. /// <summary>
  462. /// 清除绘制的对齐线
  463. /// </summary>
  464. public void ClearAlignLine()
  465. {
  466. var arr = AdornerLayer.GetAdornerLayer(this).GetAdorners(this);
  467. if (arr != null)
  468. {
  469. for (int i = arr.Length - 1; i >= 0; i--)
  470. {
  471. AdornerLayer.GetAdornerLayer(this).Remove(arr[i]);
  472. }
  473. }
  474. }
  475. public void ZoomControls(int offsetX, int offsetY)
  476. {
  477. foreach (var item in SelectedItems)
  478. {
  479. if (item.ActualHeight + offsetY > 10)
  480. {
  481. item.Height += offsetY;
  482. }
  483. if (item.ActualWidth + offsetX > 10)
  484. {
  485. item.Width += offsetX;
  486. }
  487. }
  488. }
  489. #endregion
  490. #region 对齐操作
  491. /// <summary>
  492. /// 是否使用网格对齐 10px
  493. /// </summary>
  494. public bool UseAutoAlignment
  495. {
  496. get { return (bool)GetValue(UseAutoAlignmentProperty); }
  497. set { SetValue(UseAutoAlignmentProperty, value); }
  498. }
  499. public static readonly DependencyProperty UseAutoAlignmentProperty =
  500. DependencyProperty.Register("UseAutoAlignment", typeof(bool), typeof(CanvasPanel), new PropertyMetadata(false));
  501. public void AlignLeft()
  502. {
  503. if (SelectedItems == null || SelectedItems.Count == 0)
  504. return;
  505. var leftMin = SelectedItems.Min(x => Canvas.GetLeft(x));
  506. foreach (var item in SelectedItems)
  507. {
  508. SetLeft(item, leftMin);
  509. }
  510. }
  511. public void AlignRight()
  512. {
  513. if (SelectedItems == null || SelectedItems.Count == 0)
  514. return;
  515. var rightMax = SelectedItems.Max(x => GetLeft(x) + x.ActualWidth);
  516. foreach (var item in SelectedItems)
  517. {
  518. var targetLeft = rightMax - item.ActualWidth;
  519. SetLeft(item, targetLeft);
  520. }
  521. }
  522. public void AlignCenter()
  523. {
  524. if (SelectedItems == null || SelectedItems.Count == 0)
  525. return;
  526. var leftmin = SelectedItems.Min(x => GetLeft(x));
  527. var rightmax = SelectedItems.Max(x => GetLeft(x) + x.ActualWidth);
  528. var center = (rightmax - leftmin) / 2 + leftmin;
  529. foreach (var item in SelectedItems)
  530. {
  531. var target = center - (item.ActualWidth / 2);
  532. SetLeft(item, target);
  533. }
  534. }
  535. public void AlignTop()
  536. {
  537. if (SelectedItems == null || SelectedItems.Count == 0)
  538. return;
  539. var topMin = SelectedItems.Min(x => GetTop(x));
  540. foreach (var item in SelectedItems)
  541. {
  542. SetTop(item, topMin);
  543. }
  544. }
  545. public void AlignBottom()
  546. {
  547. if (SelectedItems == null || SelectedItems.Count == 0)
  548. return;
  549. var botMax = SelectedItems.Max(x => GetTop(x) + x.ActualHeight);
  550. foreach (var item in SelectedItems)
  551. {
  552. var targetLeft = botMax - item.ActualHeight;
  553. SetTop(item, targetLeft);
  554. }
  555. }
  556. public void VertialLayout()
  557. {
  558. if (SelectedItems == null || SelectedItems.Count < 3)
  559. return;
  560. var topCtl = SelectedItems.Min(x => GetTop(x) + x.ActualHeight);
  561. var botCtrl = SelectedItems.Max(x => GetTop(x));
  562. var emptyHeight = botCtrl - topCtl;
  563. var orderCtrl = SelectedItems.OrderBy(x => GetTop(x)).ToList();
  564. orderCtrl.RemoveAt(0);
  565. orderCtrl.RemoveAt(orderCtrl.Count - 1);
  566. var useSpace = orderCtrl.Sum(x => x.ActualHeight);
  567. var ableSpaceAvg = (emptyHeight - useSpace) / (SelectedItems.Count - 1);
  568. double nowPostion = topCtl;
  569. foreach (var item in orderCtrl)
  570. {
  571. SetTop(item, nowPostion + ableSpaceAvg);
  572. nowPostion += item.ActualHeight + ableSpaceAvg;
  573. }
  574. }
  575. public void HorizontalLayout()
  576. {
  577. if (SelectedItems == null || SelectedItems.Count < 3)
  578. return;
  579. var leftCtl = SelectedItems.Min(x => GetLeft(x) + x.ActualWidth);
  580. var rightCtrl = SelectedItems.Max(x => GetLeft(x));
  581. var emptyHeight = rightCtrl - leftCtl;
  582. var orderCtrl = SelectedItems.OrderBy(x => GetLeft(x)).ToList();
  583. orderCtrl.RemoveAt(0);
  584. orderCtrl.RemoveAt(orderCtrl.Count - 1);
  585. var useSpace = orderCtrl.Sum(x => x.ActualWidth);
  586. var ableSpaceAvg = (emptyHeight - useSpace) / (SelectedItems.Count - 1);
  587. double nowPostion = leftCtl;
  588. foreach (var item in orderCtrl)
  589. {
  590. SetLeft(item, nowPostion + ableSpaceAvg);
  591. nowPostion += item.ActualWidth + ableSpaceAvg;
  592. }
  593. }
  594. #endregion
  595. #region 按键操作
  596. public RelayCommand CopySelectItemsCommand { get; set; }
  597. public RelayCommand PasteSelectItemsCommand { get; set; }
  598. public RelayCommand DeleteSelectItemsCommand { get; set; }
  599. public RelayCommand SetTopLayerCommand { get; set; }
  600. public RelayCommand SetBottomLayerCommand { get; set; }
  601. List<FrameworkElement> copyTemp = new List<FrameworkElement>();
  602. private void CanvasPanel_KeyDown(object sender, KeyEventArgs e)
  603. {
  604. if (e.Key == Key.C && Keyboard.Modifiers == ModifierKeys.Control)
  605. {
  606. CopySelectItems();
  607. }
  608. else if (e.Key == Key.V && Keyboard.Modifiers == ModifierKeys.Control)
  609. {
  610. PasteSelectItems();
  611. }
  612. else if (e.Key == Key.Delete)
  613. {
  614. DeleteSelectItems();
  615. }
  616. else if (e.Key == Key.Up)
  617. {
  618. var offset = -1;
  619. foreach (var item in SelectedItems)
  620. {
  621. SetTop(item, (GetTop(item) + offset) < 0 ? 0 : GetTop(item) + offset);
  622. }
  623. e.Handled = true;
  624. }
  625. else if (e.Key == Key.Down)
  626. {
  627. var offset = 1;
  628. foreach (var item in SelectedItems)
  629. {
  630. SetTop(item, (GetTop(item) + offset) < 0 ? 0 : GetTop(item) + offset);
  631. }
  632. e.Handled = true;
  633. }
  634. else if (e.Key == Key.Left)
  635. {
  636. var offset = -1;
  637. foreach (var item in SelectedItems)
  638. {
  639. SetLeft(item, (GetLeft(item) + offset) < 0 ? 0 : GetLeft(item) + offset);
  640. }
  641. e.Handled = true;
  642. }
  643. else if (e.Key == Key.Right)
  644. {
  645. var offset = 1;
  646. foreach (var item in SelectedItems)
  647. {
  648. SetLeft(item, (GetLeft(item) + offset) < 0 ? 0 : GetLeft(item) + offset);
  649. }
  650. e.Handled = true;
  651. }
  652. }
  653. /// <summary>
  654. /// 复制
  655. /// </summary>
  656. public void CopySelectItems()
  657. {
  658. copyTemp.Clear();
  659. foreach (var item in SelectedItems)
  660. {
  661. copyTemp.Add(item);
  662. }
  663. }
  664. /// <summary>
  665. /// 粘贴
  666. /// </summary>
  667. public void PasteSelectItems()
  668. {
  669. SelectedItems.Clear();
  670. foreach (var item in copyTemp)
  671. {
  672. var xml = XamlWriter.Save(item);
  673. var element = XamlReader.Parse(xml) as FrameworkElement;
  674. element.Name += "_1";
  675. SetLeft(element, GetLeft(element) + 10);
  676. SetTop(element, GetTop(element) + 10);
  677. Children.Add(element);
  678. SelectedItems.Add(element);
  679. }
  680. // 将复制的内容替换 以便处理连续复制
  681. copyTemp.Clear();
  682. foreach (var item in SelectedItems)
  683. {
  684. copyTemp.Add(item);
  685. }
  686. RefreshSelection();
  687. }
  688. /// <summary>
  689. /// 置于顶层
  690. /// </summary>
  691. public void SetTopLayer()
  692. {
  693. if (SelectedItems.Count == 0)
  694. return;
  695. foreach (var item in SelectedItems)
  696. {
  697. Children.Remove(item);
  698. }
  699. foreach (var item in SelectedItems)
  700. {
  701. Children.Add(item);
  702. }
  703. }
  704. /// <summary>
  705. /// 置于底层
  706. /// </summary>
  707. public void SetBottomLayer()
  708. {
  709. if (SelectedItems.Count == 0)
  710. return;
  711. foreach (var item in SelectedItems)
  712. {
  713. Children.Remove(item);
  714. }
  715. foreach (var item in SelectedItems)
  716. {
  717. Children.Insert(0, item);
  718. }
  719. }
  720. /// <summary>
  721. /// 删除
  722. /// </summary>
  723. public void DeleteSelectItems()
  724. {
  725. foreach (var item in SelectedItems)
  726. {
  727. Children.Remove(item);
  728. }
  729. SelectedItems.Clear();
  730. RefreshSelection();
  731. }
  732. #endregion
  733. #region 运行Xaml 保存 读取
  734. public List<FrameworkElement> Generator()
  735. {
  736. List<FrameworkElement> elements = new List<FrameworkElement>();
  737. foreach (var item in Children)
  738. {
  739. // 排除非自定义的控件们
  740. if (!(item is IExecutable))
  741. continue;
  742. var xml = XamlWriter.Save(item);
  743. var ele = XamlReader.Parse(xml) as FrameworkElement;
  744. elements.Add(ele);
  745. }
  746. return elements;
  747. }
  748. /// <summary>
  749. /// 保存数据到文本
  750. /// </summary>
  751. public string Save()
  752. {
  753. StringBuilder sb = new StringBuilder();
  754. foreach (var item in Children)
  755. {
  756. var xml = XamlWriter.Save(item);
  757. sb.Append(xml + "\r\n");
  758. }
  759. return sb.ToString();
  760. }
  761. /// <summary>
  762. /// 读取文件
  763. /// </summary>
  764. public void Load(string path)
  765. {
  766. Children.Clear();
  767. FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  768. using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.Unicode))
  769. {
  770. while (sr.Peek() > -1)
  771. {
  772. string str = sr.ReadLine();
  773. //if (!str.Contains("NewConveyorBelt"))
  774. {
  775. try
  776. {
  777. var ele = XamlReader.Parse(str) as FrameworkElement;
  778. Children.Add(ele);
  779. }
  780. catch (Exception ex)
  781. {
  782. }
  783. }
  784. }
  785. }
  786. SelectedItems?.Clear();
  787. }
  788. #endregion
  789. }
  790. }