using MetroGauges.Controls.BlockShaps; using MetroGauges.Database; using MetroGauges.Database.Enitys; using netDxf; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; namespace MetroGauges.Controls { public class BlockData { private bool visblie; public BlockInfo BlockEnity { get; set; } public netDxf.Blocks.Block SourceBlock { get; set; } public netDxf.Blocks.Block ReverseBlock { get; set; } public List Block { get; set; } /// /// 是否镜向 /// public bool IsDirection { get; set; } /// /// 是否能镜向 /// public bool CanDirection { get; set; } public bool Visblie { get { return visblie; } set { visblie = value; foreach (var item in this.Block) { if (visblie) { item.Visibility = Visibility.Visible; } else { item.Visibility = Visibility.Collapsed; } } } } public string BlockName { get; set; } public double Sclae { get; set; } public string FilePath { get; set; } public List BlockPoints { get; set; } public BlockData() { Sclae = 1; Block = new List(); BlockPoints = new List(); } } public class BlockManage { private BlockOpr m_blockOpr = new BlockOpr(); private string m_BlockPath; private Canvas m_canvas; private Dictionary m_Blocks = new Dictionary(); //原文件块数据 //private Dictionary sourceBlocks = new Dictionary(); private BlockData selectedBlock; private double m_ScaleRale; private System.Windows.Point dragPoint; System.Windows.Point offset; bool isInDrag = false; public event EventHandler HighlighEvent; public bool IsView { get; set; } public Point DragPoint { set { dragPoint = value; } } public Dictionary Blocks { get { return m_Blocks; } } public BlockData SelectedBlock { get { return selectedBlock; } set { selectedBlock = value; } } public BlockManage(Canvas canvas, double scaleRale) { m_canvas = canvas; m_ScaleRale = scaleRale; m_BlockPath = AppDomain.CurrentDomain.BaseDirectory + "Blocks\\"; m_blockOpr.ScaleRale = m_ScaleRale; //Ellipse ellipse = new Ellipse(); //Path path = AddCircle(new netDxf.Entities.Circle() { Center = new netDxf.Vector3() { X = 1000, Y = 1000 }, Radius=50 }); //path.Name = "圆"; //m_Blocks.Add( "圆", new List() { path } ); //AddArc(null); } public List BlockNames() { List list = new List(); try { string[] files= System.IO.Directory.GetFiles(m_BlockPath); foreach (var item in files) { string name = System.IO.Path.GetFileNameWithoutExtension(item); string[] names = name.Split('_'); list.Add(new BlockModel() { Name = names[0], FileName = name }); } } catch (Exception ex) { LogManager.WriteLog("DesingControl", "BlockNames:" + ex.Message); MessageBox.Show("获取块数据异常","错误"); } return list; } #region 图形移动 public void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { FrameworkElement element = sender as FrameworkElement; offset = e.GetPosition(element); element.CaptureMouse(); isInDrag = true; e.Handled = true; dragPoint = e.GetPosition(m_canvas); this.CopyBlock(element.Name); this.HighlightBlock(element.Name); //MessageBox.Show($"X:{offset.X}Y:{offset.Y}"); } private void Element_MouseMove(object sender, MouseEventArgs e) { if (isInDrag) { FrameworkElement element = sender as FrameworkElement; System.Windows.Point currentPoint = e.GetPosition(m_canvas); //Canvas.SetLeft(element, currentPoint.X - offset.X); //Canvas.SetTop(element, currentPoint.Y + offset.Y); //Canvas.SetLeft(x_scale1, currentPoint.X - offset.X); //Canvas.SetTop(x_scale1, currentPoint.Y + offset.Y); MoveBlock(element.Name, currentPoint); SendHighlighEvent(false); } } private void Element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (isInDrag) { FrameworkElement element = sender as FrameworkElement; element.ReleaseMouseCapture(); isInDrag = false; e.Handled = true; if (!IsView) { SendHighlighEvent(true); } } } #endregion //高亮选择块 public void HighlightBlock(string blockname) { if (selectedBlock != null) { foreach (var item in selectedBlock.Block) { if (item is Shape) { (item as Shape).Stroke = Brushes.White; } } } if (m_Blocks.ContainsKey(blockname)) { selectedBlock = m_Blocks[blockname]; foreach (var item in selectedBlock.Block) { if (item is Shape) { (item as Shape).Stroke = Brushes.Red; } } } SendHighlighEvent(false); } public void SendHighlighEvent(bool isNeedUpdateDB) { if (HighlighEvent != null) { HighlighEvent e = new HighlighEvent() { Block = selectedBlock }; Point minPoint = new Point(); Point cenPoint = new Point(); m_blockOpr.GetBlockPoints(selectedBlock.Block, out minPoint, out cenPoint); e.Location = minPoint; HighlighEvent(this, e); if (isNeedUpdateDB && selectedBlock.BlockEnity !=null) { //更新最后调整位置:矩形外框右下角位置 BlockDAL.UpdateBlockLocation(selectedBlock.BlockEnity.Id, minPoint.X, minPoint.Y); selectedBlock.BlockEnity.Locationx = minPoint.X; selectedBlock.BlockEnity.Locationy = minPoint.Y; } } } public void RemoveBlock() { if (selectedBlock != null) { foreach (var item in selectedBlock.Block) { this.m_canvas.Children.Remove(item); } m_Blocks.Remove(selectedBlock.BlockName); } } public void RemoveBlock(BlockData block) { if (block != null) { foreach (var item in block.Block) { this.m_canvas.Children.Remove(item); } m_Blocks.Remove(block.BlockName); } } /// /// 添加 镜向块 /// /// public Shape ReverseBlock() { Shape drapShape = null; if (selectedBlock != null && selectedBlock.ReverseBlock !=null) { //RemoveBlock(); //drapShape = EntityToShap(selectedBlock.ReverseBlock, selectedBlock); //selectedBlock.SourceBlock = selectedBlock.ReverseBlock; //m_Blocks.Add(selectedBlock.BlockName, selectedBlock); if (!selectedBlock.IsDirection) { TransformGroup tg = new TransformGroup(); ScaleTransform scale = new ScaleTransform() { ScaleX = -1 }; tg.Children.Add(scale); foreach (var item in selectedBlock.Block) { item.RenderTransform = tg; (item.DataContext as ShapDataContext).IsDirection = true; } } else { foreach (var item in selectedBlock.Block) { item.RenderTransform = null; (item.DataContext as ShapDataContext).IsDirection = false; } } selectedBlock.IsDirection = !selectedBlock.IsDirection; } return drapShape; } /// /// 添加块图形 /// /// public Shape AddBlock(string blockname,bool isDirection =false) { Shape drapShape = null; try { blockname = blockname.Replace(".dxf",""); if (!string.IsNullOrEmpty(blockname)) { string bName = blockname + "_" + (m_Blocks.Count+1); BlockData blockData = new BlockData() { BlockName=bName, IsDirection= isDirection }; m_Blocks.Add(bName, blockData); string file = m_BlockPath + blockname + ".dxf"; blockData.FilePath = file; //string[] names = blockname.Split('_'); netDxf.DxfDocument dxf = netDxf.DxfDocument.Load(file); blockData.SourceBlock=dxf.Blocks[blockname]; //blockData.ReverseBlock= dxf.Blocks[names[0]+"B"]; //foreach (var blName in names) //根据命名规侧循环嵌套的块 //{ if (dxf.Blocks.Contains(blockname)) { netDxf.Blocks.Block block = dxf.Blocks[blockname]; drapShape = EntityToShap(block, blockData); } // } return drapShape; } } catch (Exception ex) { LogManager.WriteLog("DesingControl", "AddBlock:" + ex.Message); MessageBox.Show("读取块数据异常","错误"); } return drapShape; } private Shape EntityToShap(netDxf.Blocks.Block block, BlockData blockData) { Shape drapShape = null; for (int i = 0; i < block.Entities.Count; i++) { netDxf.Entities.EntityObject item = block.Entities[i]; switch (item.Type.ToString()) { case "Line": Line line = AddLine(item); line.Name = blockData.BlockName; blockData.Block.Add(line); drapShape = line; item.DataContext = line; break; case "Polyline": case "LightWeightPolyline": Polyline ply = AddPolyline(item); ply.Name = blockData.BlockName; blockData.Block.Add(ply); drapShape = new Line() { X1 = ply.Points[0].X, Y1 = ply.Points[1].Y, Name = blockData.BlockName }; item.DataContext = ply; break; case "Circle": Path circle = AddCircle(item); circle.Name = blockData.BlockName; blockData.Block.Add(circle); EllipseGeometry cir = circle.Data as EllipseGeometry; drapShape = new Line() { X1 = cir.Center.X, Y1 = cir.Center.Y, Name = blockData.BlockName }; item.DataContext = circle; break; case "Arc": Path arc = AddArc(item); arc.Name = blockData.BlockName; blockData.Block.Add(arc); drapShape = arc; item.DataContext = arc; break; } //记录反转的块的某个点,作为插入块时的偏移计算 if (blockData.ReverseBlock != null) { blockData.ReverseBlock.Entities[i].DataContext = drapShape; } } return drapShape; } #region 添加图形到画板中 public Line AddLine(netDxf.Entities.EntityObject line) { double xyRate = m_ScaleRale; Line drawline = new Line() { Cursor =Cursors.Hand }; netDxf.Entities.Line dataLine = line as netDxf.Entities.Line; drawline.X1 = dataLine.StartPoint.X / xyRate; drawline.Y1 = -dataLine.StartPoint.Y / xyRate; drawline.X2 = dataLine.EndPoint.X / xyRate; drawline.Y2 = -dataLine.EndPoint.Y / xyRate; drawline.Stroke = Brushes.White; drawline.StrokeThickness = 0.5; drawline.MouseLeftButtonDown += Element_MouseLeftButtonDown; drawline.MouseMove += Element_MouseMove; drawline.MouseLeftButtonUp += Element_MouseLeftButtonUp; // 保存原始坐标 drawline.DataContext = new ShapDataContext() { OringLocation = new Line() { X1 = drawline.X1, Y1 = drawline.Y1, X2 = drawline.X2, Y2 = drawline.Y2 } }; m_canvas.Children.Add(drawline); return drawline; } public Polyline AddPolyline(netDxf.Entities.EntityObject line) { double xyRate = m_ScaleRale; PointCollection ptcol = new PointCollection(); bool isClosed = false; switch (line.Type.ToString()) { case "Polyline": netDxf.Entities.Polyline polyline = line as netDxf.Entities.Polyline; foreach (netDxf.Entities.PolylineVertex item in polyline.Vertexes) { ptcol.Add(new Point() { X = item.Location.X / xyRate, Y = -item.Location.Y / xyRate }); } if (polyline.IsClosed) { netDxf.Vector3 last = polyline.Vertexes[0].Location; ptcol.Add(new Point() { X = last.X / xyRate, Y = -last.Y / xyRate }); } isClosed = polyline.IsClosed; break; case "LightWeightPolyline": netDxf.Entities.LwPolyline lwline = line as netDxf.Entities.LwPolyline; foreach (var item in lwline.Vertexes) { ptcol.Add(new Point() { X = item.Location.X / xyRate, Y = -item.Location.Y / xyRate }); } if (lwline.IsClosed) { netDxf.Vector2 last = lwline.Vertexes[0].Location; ptcol.Add(new Point() { X = last.X / xyRate, Y = -last.Y / xyRate }); } isClosed = lwline.IsClosed; break; } Polyline pl = new Polyline { Stroke = Brushes.White, StrokeThickness = 0.5, Points = ptcol, Cursor = Cursors.Hand }; pl.MouseLeftButtonDown += Element_MouseLeftButtonDown; pl.MouseMove += Element_MouseMove; pl.MouseLeftButtonUp += Element_MouseLeftButtonUp; // 保存原始坐标 pl.DataContext = new ShapDataContext() { OringLocation = pl.Points, IsClosed= isClosed }; m_canvas.Children.Add(pl); return pl; } public Path AddCircle(netDxf.Entities.EntityObject circle1) { netDxf.Entities.Circle circle = circle1 as netDxf.Entities.Circle; double xyRate = m_ScaleRale; Path path = new Path() { Stroke = new SolidColorBrush(Colors.White), StrokeThickness = 0.5, Cursor = Cursors.Hand }; EllipseGeometry ellipseGeometry = new EllipseGeometry() { RadiusX = circle.Radius / xyRate, RadiusY = circle.Radius/ xyRate, Center = new Point() { X = circle.Center.X/ xyRate, Y = -circle.Center.Y / xyRate } }; path.Data = ellipseGeometry; path.MouseLeftButtonDown += Element_MouseLeftButtonDown; path.MouseMove += Element_MouseMove; path.MouseLeftButtonUp += Element_MouseLeftButtonUp; //保存原始坐标 EllipseGeometry geometry = new EllipseGeometry(); geometry.Center = new Point() { X = ellipseGeometry.Center.X, Y = ellipseGeometry.Center.Y }; geometry.RadiusX = ellipseGeometry.RadiusX; geometry.RadiusY = ellipseGeometry.RadiusY; path.DataContext = new ShapDataContext() { OringLocation = geometry }; m_canvas.Children.Add(path); return path; } public Path AddArc(netDxf.Entities.EntityObject arc1) { netDxf.Entities.Arc arc = arc1 as netDxf.Entities.Arc; Path path = new Path() { Cursor = Cursors.Hand }; path.MouseLeftButtonDown += Element_MouseLeftButtonDown; path.MouseMove += Element_MouseMove; path.MouseLeftButtonUp += Element_MouseLeftButtonUp; double startAngleInRadian = arc.StartAngle * Math.PI / 180.0; double endAngleInRadian = arc.EndAngle * Math.PI / 180.0; Point arcStartPt = new Point(); Point arcEndPt = new Point(); arcStartPt.X = arc.Center.X + arc.Radius * Math.Cos(startAngleInRadian); arcStartPt.Y = arc.Center.Y + arc.Radius * Math.Sin(startAngleInRadian); arcEndPt.X = arc.Center.X + arc.Radius * Math.Cos(endAngleInRadian); arcEndPt.Y = arc.Center.Y + arc.Radius * Math.Sin(endAngleInRadian); PathGeometry pathGeometry = new PathGeometry(); ArcSegment arcs = new ArcSegment(new Point(arcEndPt.X/ m_ScaleRale, -arcEndPt.Y/ m_ScaleRale), new Size(arc.Radius/ m_ScaleRale, arc.Radius/ m_ScaleRale), 0, false, SweepDirection.Counterclockwise, true); PathFigure figure = new PathFigure(); figure.StartPoint = new Point(arcStartPt.X/ m_ScaleRale, -arcStartPt.Y/ m_ScaleRale); figure.Segments.Add(arcs); pathGeometry.Figures.Add(figure); path.Data = pathGeometry; path.Stroke = Brushes.White; path.StrokeThickness = 0.5; arc.Center = new Vector3() { X = arc.Center.X / m_ScaleRale, Y = -arc.Center.Y / m_ScaleRale }; arc.Radius = arc.Radius / m_ScaleRale; ShapDataContext shapDataContext =new ShapDataContext() { Arc=arc }; //new Point() { X = arc.Center.X, Y = arc.Center.Y }; path.DataContext = shapDataContext; ////保存原始坐标 List ps = new List(); ps.Add(new Point() { X = figure.StartPoint.X, Y = figure.StartPoint.Y }); ps.Add(new Point() { X = arcs.Point.X, Y = arcs.Point.Y }); ps.Add(new Point() { X = shapDataContext.Arc.Center.X, Y = shapDataContext.Arc.Center.Y }); shapDataContext.OringLocation = ps; m_canvas.Children.Add(path); return path; } #endregion /// /// 导出所有的多块图形 /// /// /// public void DrawDxfBlocks(netDxf.DxfDocument dxf, netDxf.Tables.Layer layer) { Dictionary blocks = m_Blocks; foreach (var item in blocks) { List block = item.Value.Block; m_blockOpr.dxf = dxf; m_blockOpr.layer = layer; m_blockOpr.BlockData = item.Value; //m_blockOpr.ExctecOpr(block, OprType.DrawDxfBlocks); m_blockOpr.ExctecOpr(block, OprType.ExportSourceBlock); } } /// /// 设置块图形的原始坐标 计算拖动使用 /// /// public void CopyBlock( string blockname ) { if (!string.IsNullOrWhiteSpace(blockname)) { List block = m_Blocks[blockname].Block; m_blockOpr.ExctecOpr(block, OprType.CopyBlock); } } public void MoveBlock(string blockName, System.Windows.Point currentPoint) { BlockData blockData = m_Blocks[blockName]; if (blockData.BlockEnity !=null && blockData.BlockEnity.Istemplate == 0) { List blocks = blockData.Block; m_blockOpr.currentPoint = currentPoint; m_blockOpr.dragPoint = dragPoint; m_blockOpr.ExctecOpr(blocks, OprType.MoveBlock); } } public void ScaleBlock( double rate) { if (selectedBlock != null && rate!=0) { this.CopyBlock(selectedBlock.BlockName); m_blockOpr.rate = rate; List block = selectedBlock.Block; selectedBlock.Sclae = rate; if (selectedBlock != null ) { m_blockOpr.ExctecOpr(block, OprType.ScaleBlock); } } } public void MoveBlockByX(string blockName, double x) { List blocks = m_Blocks[blockName].Block; m_blockOpr.currentPoint = new Point() { X =x }; m_blockOpr.ExctecOpr(blocks, OprType.MoveByX); } public void MoveBlockByY(string blockName, double y) { List blocks = m_Blocks[blockName].Block; m_blockOpr.currentPoint = new Point() { Y = y }; m_blockOpr.ExctecOpr(blocks, OprType.MoveByY); } } }