DiagramView.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows.Controls;
  5. using System.Windows.Documents;
  6. using System.Windows;
  7. using System.Windows.Media;
  8. using System.Windows.Input;
  9. namespace SHJX.Service.WorkFlowEdit
  10. {
  11. public class DiagramView : Canvas
  12. {
  13. private Pen _gridPen;
  14. static DiagramView()
  15. {
  16. FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
  17. typeof(DiagramView), new FrameworkPropertyMetadata(typeof(DiagramView)));
  18. }
  19. #region Properties
  20. #region GridCellSize
  21. public static readonly DependencyProperty GridCellSizeProperty =
  22. DependencyProperty.Register("GridCellSize",
  23. typeof(Size),
  24. typeof(DiagramView),
  25. new FrameworkPropertyMetadata(new Size(10, 10)));
  26. public Size GridCellSize
  27. {
  28. get { return (Size)GetValue(GridCellSizeProperty); }
  29. set { SetValue(GridCellSizeProperty, value); }
  30. }
  31. #endregion
  32. #region ShowGrid
  33. public static readonly DependencyProperty ShowGridProperty =
  34. DependencyProperty.Register("ShowGrid",
  35. typeof(bool),
  36. typeof(DiagramView),
  37. new FrameworkPropertyMetadata(false));
  38. public bool ShowGrid
  39. {
  40. get { return (bool)GetValue(ShowGridProperty); }
  41. set { SetValue(ShowGridProperty, value); }
  42. }
  43. #endregion
  44. #region DocumentSize
  45. public static readonly DependencyProperty DocumentSizeProperty =
  46. DependencyProperty.Register("DocumentSize",
  47. typeof(Size),
  48. typeof(DiagramView),
  49. new FrameworkPropertyMetadata(new Size(2000, 2000)));
  50. public Size DocumentSize
  51. {
  52. get { return (Size)GetValue(DocumentSizeProperty); }
  53. set { SetValue(DocumentSizeProperty, value); }
  54. }
  55. #endregion
  56. #region Zoom
  57. public static readonly DependencyProperty ZoomProperty =
  58. DependencyProperty.Register("Zoom",
  59. typeof(double),
  60. typeof(DiagramView),
  61. new FrameworkPropertyMetadata(1.0, new PropertyChangedCallback(OnZoomChanged)));
  62. private static void OnZoomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  63. {
  64. var view = d as DiagramView;
  65. var zoom = (double)e.NewValue;
  66. view._gridPen = view.CreateGridPen();
  67. if (Math.Abs(zoom - 1) < 0.0001)
  68. view.LayoutTransform = null;
  69. else
  70. view.LayoutTransform = new ScaleTransform(zoom, zoom);
  71. }
  72. public double Zoom
  73. {
  74. get { return (double)GetValue(ZoomProperty); }
  75. set { SetValue(ZoomProperty, value); }
  76. }
  77. #endregion
  78. public Selection Selection { get; private set; }
  79. public IDiagramController Controller { get; set; }
  80. public IEnumerable<DiagramItem> Items
  81. {
  82. get { return Children.OfType<DiagramItem>(); }
  83. }
  84. private IInputTool _inputTool;
  85. public IInputTool InputTool
  86. {
  87. get { return _inputTool; }
  88. set
  89. {
  90. if (value == null)
  91. throw new ArgumentNullException("value");
  92. _inputTool = value;
  93. }
  94. }
  95. private IMoveResizeTool _dragTool;
  96. public IMoveResizeTool DragTool
  97. {
  98. get { return _dragTool; }
  99. set
  100. {
  101. if (value == null)
  102. throw new ArgumentNullException("value");
  103. _dragTool = value;
  104. }
  105. }
  106. private ILinkTool _linkTool;
  107. public ILinkTool LinkTool
  108. {
  109. get { return _linkTool; }
  110. set
  111. {
  112. _linkTool = value ?? throw new ArgumentNullException("value");
  113. }
  114. }
  115. public IDragDropTool DragDropTool { get; set; }
  116. private Adorner _dragAdorner;
  117. public Adorner DragAdorner
  118. {
  119. get { return _dragAdorner; }
  120. set
  121. {
  122. if (_dragAdorner != value)
  123. {
  124. var adornerLayer = AdornerLayer.GetAdornerLayer(this);
  125. if (_dragAdorner != null)
  126. adornerLayer.Remove(_dragAdorner);
  127. _dragAdorner = value;
  128. if (_dragAdorner != null)
  129. adornerLayer.Add(_dragAdorner);
  130. }
  131. }
  132. }
  133. public bool IsDragging { get { return DragAdorner != null; } }
  134. #endregion
  135. public DiagramView()
  136. {
  137. _gridPen = CreateGridPen();
  138. Selection = new Selection();
  139. InputTool = new InputTool(this);
  140. DragTool = new MoveResizeTool(this);
  141. LinkTool = new LinkTool(this);
  142. BindCommands();
  143. Focusable = true;
  144. this.LayoutUpdated += new EventHandler(DiagramView_LayoutUpdated);
  145. }
  146. void DiagramView_LayoutUpdated(object sender, EventArgs e)
  147. {
  148. foreach (var n in Children.OfType<Node>())
  149. n.UpdatePosition();
  150. }
  151. public DiagramItem FindItem(object modelElement)
  152. {
  153. return Items.FirstOrDefault(p => p.ModelElement == modelElement);
  154. }
  155. protected override void OnMouseDown(MouseButtonEventArgs e)
  156. {
  157. InputTool.OnMouseDown(e);
  158. base.OnMouseDown(e);
  159. Focus();
  160. }
  161. protected override void OnMouseMove(MouseEventArgs e)
  162. {
  163. InputTool.OnMouseMove(e);
  164. base.OnMouseMove(e);
  165. }
  166. protected override void OnMouseUp(MouseButtonEventArgs e)
  167. {
  168. InputTool.OnMouseUp(e);
  169. base.OnMouseUp(e);
  170. }
  171. protected override void OnPreviewKeyDown(KeyEventArgs e)
  172. {
  173. InputTool.OnPreviewKeyDown(e);
  174. base.OnPreviewKeyDown(e);
  175. }
  176. protected override void OnDragEnter(DragEventArgs e)
  177. {
  178. if (DragDropTool != null)
  179. DragDropTool.OnDragEnter(e);
  180. base.OnDragEnter(e);
  181. }
  182. protected override void OnDragLeave(DragEventArgs e)
  183. {
  184. if (DragDropTool != null)
  185. DragDropTool.OnDragLeave(e);
  186. base.OnDragLeave(e);
  187. }
  188. protected override void OnDragOver(DragEventArgs e)
  189. {
  190. if (DragDropTool != null)
  191. DragDropTool.OnDragOver(e);
  192. base.OnDragOver(e);
  193. }
  194. protected override void OnDrop(DragEventArgs e)
  195. {
  196. if (DragDropTool != null)
  197. DragDropTool.OnDrop(e);
  198. base.OnDrop(e);
  199. }
  200. protected override Size MeasureOverride(Size constraint)
  201. {
  202. base.MeasureOverride(DocumentSize);
  203. return DocumentSize;
  204. }
  205. protected override void OnRender(DrawingContext dc)
  206. {
  207. var rect = new Rect(0, 0, RenderSize.Width, RenderSize.Height);
  208. dc.DrawRectangle(Background, null, rect);
  209. if (ShowGrid && GridCellSize.Width > 0 && GridCellSize.Height > 0)
  210. DrawGrid(dc, rect);
  211. }
  212. protected virtual void DrawGrid(DrawingContext dc, Rect rect)
  213. {
  214. //using .5 forces wpf to draw a single pixel line
  215. for (var i = 0.5; i < rect.Height; i += GridCellSize.Height)
  216. dc.DrawLine(_gridPen, new Point(0, i), new Point(rect.Width, i));
  217. for (var i = 0.5; i < rect.Width; i += GridCellSize.Width)
  218. dc.DrawLine(_gridPen, new Point(i, 0), new Point(i, rect.Height));
  219. }
  220. protected virtual Pen CreateGridPen()
  221. {
  222. return new Pen(Brushes.LightGray, (1 / Zoom));
  223. }
  224. private void BindCommands()
  225. {
  226. CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, ExecuteCommand, CanExecuteCommand));
  227. CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, ExecuteCommand, CanExecuteCommand));
  228. CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, ExecuteCommand, CanExecuteCommand));
  229. CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, ExecuteCommand, CanExecuteCommand));
  230. }
  231. private void ExecuteCommand(object sender, ExecutedRoutedEventArgs e)
  232. {
  233. if (Controller != null)
  234. Controller.ExecuteCommand(e.Command, e.Parameter);
  235. if (e.Command == ApplicationCommands.Delete)
  236. Selection.Clear();
  237. }
  238. private void CanExecuteCommand(object sender, CanExecuteRoutedEventArgs e)
  239. {
  240. if (Controller != null)
  241. e.CanExecute = Controller.CanExecuteCommand(e.Command, e.Parameter);
  242. }
  243. }
  244. }