Files
MetroGauges-Old/MetroGauges/Controls/BlockManage.cs

706 lines
24 KiB
C#
Raw Normal View History

2026-02-23 17:02:55 +08:00
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<FrameworkElement> Block { get; set; }
/// <summary>
/// 是否镜向
/// </summary>
public bool IsDirection { get; set; }
/// <summary>
/// 是否能镜向
/// </summary>
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<Point> BlockPoints { get; set; }
public BlockData() {
Sclae = 1;
Block = new List<FrameworkElement>();
BlockPoints = new List<Point>();
}
}
public class BlockManage
{
private BlockOpr m_blockOpr = new BlockOpr();
private string m_BlockPath;
private Canvas m_canvas;
private Dictionary<string, BlockData> m_Blocks = new Dictionary<string, BlockData>();
//原文件块数据
//private Dictionary<string, netDxf.Blocks.Block> sourceBlocks = new Dictionary<string, netDxf.Blocks.Block>();
private BlockData selectedBlock;
private double m_ScaleRale;
private System.Windows.Point dragPoint;
System.Windows.Point offset;
bool isInDrag = false;
public event EventHandler<HighlighEvent> HighlighEvent;
public bool IsView { get; set; }
public Point DragPoint {
set {
dragPoint = value;
}
}
public Dictionary<string, BlockData> 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<Shape>() { path } );
//AddArc(null);
}
public List<BlockModel> BlockNames()
{
List<BlockModel> list = new List<BlockModel>();
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);
}
}
/// <summary>
/// 添加 镜向块
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// 添加块图形
/// </summary>
/// <param name="blockname"></param>
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<Point> ps = new List<Point>();
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
/// <summary>
/// 导出所有的多块图形
/// </summary>
/// <param name="dxf"></param>
/// <param name="layer"></param>
public void DrawDxfBlocks(netDxf.DxfDocument dxf, netDxf.Tables.Layer layer)
{
Dictionary<string, BlockData> blocks = m_Blocks;
foreach (var item in blocks)
{
List<FrameworkElement> 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);
}
}
/// <summary>
/// 设置块图形的原始坐标 计算拖动使用
/// </summary>
/// <param name="blockname"></param>
public void CopyBlock( string blockname )
{
if (!string.IsNullOrWhiteSpace(blockname))
{
List<FrameworkElement> 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<FrameworkElement> 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<FrameworkElement> block = selectedBlock.Block;
selectedBlock.Sclae = rate;
if (selectedBlock != null )
{
m_blockOpr.ExctecOpr(block, OprType.ScaleBlock);
}
}
}
public void MoveBlockByX(string blockName, double x)
{
List<FrameworkElement> 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<FrameworkElement> blocks = m_Blocks[blockName].Block;
m_blockOpr.currentPoint = new Point() { Y = y };
m_blockOpr.ExctecOpr(blocks, OprType.MoveByY);
}
}
}