DxfView.xaml.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. using netDxf.Entities;
  2. using OxyPlot;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Documents;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Imaging;
  15. using System.Windows.Navigation;
  16. using System.Windows.Shapes;
  17. using WpfLine = System.Windows.Shapes.Line;
  18. using DxfLine = netDxf.Entities.Line;
  19. using DxfLwPolyline = netDxf.Entities.Polyline2D;
  20. using Microsoft.Win32;
  21. namespace TeamAAS_VP.DxfModule
  22. {
  23. /// <summary>
  24. /// DxfView.xaml 的交互逻辑
  25. /// </summary>
  26. public partial class DxfView : UserControl
  27. {
  28. private DxfParserService _dxfParser;
  29. private InteractionController _interactionController;
  30. private double _currentScale = 1.0;
  31. private double _zoomFactor = 1.2;
  32. public DxfView()
  33. {
  34. InitializeComponent();
  35. _dxfParser = new DxfParserService();
  36. InitializeInteractionController();
  37. }
  38. private void InitializeInteractionController()
  39. {
  40. _interactionController = new InteractionController(DrawingCanvas);
  41. _interactionController.SelectionChanged += OnSelectionChanged;
  42. }
  43. private void BtnLoadDxf_Click(object sender, RoutedEventArgs e)
  44. {
  45. var openFileDialog = new OpenFileDialog
  46. {
  47. Filter = "DXF文件 (*.dxf)|*.dxf|所有文件 (*.*)|*.*",
  48. Title = "选择DXF文件"
  49. };
  50. if (openFileDialog.ShowDialog() == true)
  51. {
  52. LoadDxfFile(openFileDialog.FileName);
  53. }
  54. }
  55. private void LoadDxfFile(string filePath)
  56. {
  57. TxtStatus.Text = "正在加载DXF文件...";
  58. DrawingCanvas.Children.Clear();
  59. _interactionController?.ClearSelection();
  60. if (_dxfParser.LoadDxfFile(filePath))
  61. {
  62. var entities = _dxfParser.GetAllEntities();
  63. TxtStatus.Text = $"成功加载: {System.IO.Path.GetFileName(filePath)}";
  64. TxtEntityCount.Text = $"实体数: {entities.Count}";
  65. // Calculate bounds and scale
  66. var bounds = _dxfParser.GetBounds();
  67. double boundsWidth = bounds.maxX - bounds.minX;
  68. double boundsHeight = bounds.maxY - bounds.minY;
  69. if (boundsWidth > 0 && boundsHeight > 0)
  70. {
  71. double scaleX = (DrawingCanvas.Width * 0.8) / boundsWidth;
  72. double scaleY = (DrawingCanvas.Height * 0.8) / boundsHeight;
  73. _currentScale = Math.Min(scaleX, scaleY);
  74. }
  75. // Render entities
  76. foreach (var entity in entities)
  77. {
  78. var renderedElements = GraphicsRenderer.RenderEntity(entity, _currentScale);
  79. foreach (var element in renderedElements)
  80. {
  81. DrawingCanvas.Children.Add(element);
  82. }
  83. }
  84. // Center the drawing
  85. CenterDrawing(bounds);
  86. // Update statistics
  87. UpdateStatistics();
  88. }
  89. else
  90. {
  91. TxtStatus.Text = "加载DXF文件失败";
  92. MessageBox.Show("无法加载DXF文件,请检查文件是否有效。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  93. }
  94. }
  95. private void CenterDrawing((double minX, double minY, double maxX, double maxY) bounds)
  96. {
  97. double centerX = (bounds.minX + bounds.maxX) / 2 * _currentScale;
  98. double centerY = -(bounds.minY + bounds.maxY) / 2 * _currentScale;
  99. double offsetX = DrawingCanvas.Width / 2 - centerX;
  100. double offsetY = DrawingCanvas.Height / 2 - centerY;
  101. // Translate all elements
  102. foreach (UIElement element in DrawingCanvas.Children)
  103. {
  104. if (element is WpfLine line)
  105. {
  106. line.X1 += offsetX;
  107. line.X2 += offsetX;
  108. line.Y1 += offsetY;
  109. line.Y2 += offsetY;
  110. }
  111. else if (element is FrameworkElement fe)
  112. {
  113. double left = Canvas.GetLeft(fe);
  114. double top = Canvas.GetTop(fe);
  115. Canvas.SetLeft(fe, left + offsetX);
  116. Canvas.SetTop(fe, top + offsetY);
  117. }
  118. }
  119. }
  120. private void UpdateStatistics()
  121. {
  122. var stats = _dxfParser.GetEntityStatistics();
  123. var sb = new StringBuilder();
  124. foreach (var stat in stats.OrderByDescending(s => s.Value))
  125. {
  126. if (stat.Value > 0)
  127. {
  128. sb.AppendLine($"{stat.Key}: {stat.Value}");
  129. }
  130. }
  131. TxtStatistics.Text = sb.ToString();
  132. }
  133. private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
  134. {
  135. TxtSelectedCount.Text = $"选中: {e.SelectedEntities.Count}";
  136. var sb = new StringBuilder();
  137. if (e.SelectedEntities.Count > 0)
  138. {
  139. sb.AppendLine($"已选择 {e.SelectedEntities.Count} 个图形实体:\n");
  140. var grouped = e.SelectedEntities.GroupBy(entity => entity.Type.ToString());
  141. foreach (var group in grouped)
  142. {
  143. sb.AppendLine($"{group.Key}: {group.Count()}");
  144. }
  145. sb.AppendLine("\n详细信息:");
  146. int index = 1;
  147. foreach (var entity in e.SelectedEntities.Take(10))
  148. {
  149. sb.AppendLine($"\n[{index}] {GetEntityInfo(entity)}");
  150. index++;
  151. }
  152. if (e.SelectedEntities.Count > 10)
  153. {
  154. sb.AppendLine($"\n... 还有 {e.SelectedEntities.Count - 10} 个实体");
  155. }
  156. }
  157. else
  158. {
  159. sb.AppendLine("未选择任何图形");
  160. }
  161. TxtSelectedInfo.Text = sb.ToString();
  162. }
  163. private string GetEntityInfo(EntityObject entity)
  164. {
  165. switch (entity)
  166. {
  167. case DxfLine line:
  168. return $"直线: ({line.StartPoint.X:F2}, {line.StartPoint.Y:F2}) → ({line.EndPoint.X:F2}, {line.EndPoint.Y:F2})";
  169. case Circle circle:
  170. return $"圆: 中心({circle.Center.X:F2}, {circle.Center.Y:F2}), 半径={circle.Radius:F2}";
  171. case Arc arc:
  172. return $"圆弧: 中心({arc.Center.X:F2}, {arc.Center.Y:F2}), 半径={arc.Radius:F2}, 角度={arc.StartAngle:F1}°~{arc.EndAngle:F1}°";
  173. case Text text:
  174. return $"文本: \"{text.Value}\" 位置({text.Position.X:F2}, {text.Position.Y:F2})";
  175. case MText mtext:
  176. return $"多行文本: \"{mtext.Value}\" 位置({mtext.Position.X:F2}, {mtext.Position.Y:F2})";
  177. case DxfLwPolyline lwPoly:
  178. return $"轻量多段线: {lwPoly.Vertexes.Count} 个顶点{(lwPoly.IsClosed ? " (闭合)" : "")}";
  179. case Spline spline:
  180. // return $"样条曲线: {spline.ControlPoints.Count} 个控制点";
  181. default:
  182. return $"{entity.Type}: {entity.CodeName}";
  183. }
  184. }
  185. private void BtnClearSelection_Click(object sender, RoutedEventArgs e)
  186. {
  187. _interactionController?.ClearSelection();
  188. }
  189. private void BtnExtractSelected_Click(object sender, RoutedEventArgs e)
  190. {
  191. var selectedEntities = _interactionController?.GetSelectedEntities();
  192. if (selectedEntities == null || selectedEntities.Count == 0)
  193. {
  194. MessageBox.Show("请先选择要提取的图形。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
  195. return;
  196. }
  197. var sb = new StringBuilder();
  198. sb.AppendLine($"提取的图形信息 (共 {selectedEntities.Count} 个):\n");
  199. var grouped = selectedEntities.GroupBy(p => p.Type.ToString());
  200. foreach (var group in grouped)
  201. {
  202. sb.AppendLine($"\n{group.Key} ({group.Count()} 个):");
  203. sb.AppendLine(new string('-', 50));
  204. foreach (var entity in group)
  205. {
  206. sb.AppendLine(GetEntityInfo(entity));
  207. }
  208. }
  209. MessageBox.Show(sb.ToString(), "提取的图形信息", MessageBoxButton.OK, MessageBoxImage.Information);
  210. }
  211. private void BtnZoomIn_Click(object sender, RoutedEventArgs e)
  212. {
  213. Zoom(_zoomFactor);
  214. }
  215. private void BtnZoomOut_Click(object sender, RoutedEventArgs e)
  216. {
  217. Zoom(1.0 / _zoomFactor);
  218. }
  219. private void BtnFitToScreen_Click(object sender, RoutedEventArgs e)
  220. {
  221. CanvasScaleTransform.ScaleX = 1.0;
  222. CanvasScaleTransform.ScaleY = 1.0;
  223. UpdateZoomDisplay();
  224. }
  225. private void DrawingCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
  226. {
  227. double zoom = e.Delta > 0 ? _zoomFactor : 1.0 / _zoomFactor;
  228. Zoom(zoom);
  229. }
  230. private void Zoom(double factor)
  231. {
  232. CanvasScaleTransform.ScaleX *= factor;
  233. CanvasScaleTransform.ScaleY *= factor;
  234. UpdateZoomDisplay();
  235. }
  236. private void UpdateZoomDisplay()
  237. {
  238. TxtZoom.Text = $"缩放: {CanvasScaleTransform.ScaleX * 100:F0}%";
  239. }
  240. }
  241. }