C#自己开发AGV地图编辑软件:
1、自由添加和删除站点、停车位、小车、运行路径。
2、编辑得地图以XML文件保存。
3、导入编辑好地图的XML文件。
4、程序都是源码,可以直接在此基础上进行二次开发。
下载链接:https://download.csdn.net/download/panjinliang066333/88855372
部分代码展示:
#region 限制闪屏
protected override CreateParams CreateParams
{
get
{
const int WS_MINIMIZEBOX = 0x00020000; // Winuser.h中定义
CreateParams cp = base.CreateParams;
cp.Style = cp.Style | WS_MINIMIZEBOX; // 允许最小化操作
return cp;
}
}
#endregion
NodeType newType = NodeType.MousePick;
MapPanel mapPanelDocker;
FloydHelper floydCurrent;
#region AGV配置信息
int AGVCount = 0;
object[] lockObj;//线程间锁
MapVehicle[] myAgvModel;
//---占据的单元
Dictionary<string, string> LockUnit = new Dictionary<string, string>();
#endregion
#region 画布属性
private int maxScale = 0; //X轴最大刻度
private static int AxisOffset = 32;//X轴的Y坐标偏移量
private Font font = new Font("宋体", 9F, FontStyle.Regular); //刻度值显示字体
bool showRule = true;
bool showNetLine = true;
public static int MonitorDPI = 12;//单位内像素点
public static float scaling = 1.0F; //缩放比例
#endregion
#region 变量
#region 其他窗体
frm_ModelProperty frm_Property;
#endregion
#endregion
#region 其他窗体
LoadingForm loadForm;
#endregion
#region 窗体初始化
#region 初始化
public frm_AGVMain()
{
InitializeComponent();
loadForm = new LoadingForm();
loadForm.ShowLoadingDealy(3);
mapPanelDocker = new MapPanel();
mapPanelDocker.Size = this.pnlMap.Size;
mapPanelDocker.Location = new Point(0, 0);
mapPanelDocker.BorderStyle = BorderStyle.FixedSingle;
mapPanelDocker.MouseClick += mapPanel1_MouseClick;
mapPanelDocker.MouseMove += mapPanelDocker_MouseMove;
mapPanelDocker.MouseLeave += mapPanelDocker_MouseLeave;
this.pnlMap.Controls.Add(mapPanelDocker);
mapPanelDocker.LinePropertySelect += MapPanelDocker_LinePropertySelect;
mapPanelDocker.MapNodePropertySelect += MapPanelDocker_CirclePropertySelect;
mapPanelDocker.BezierLinePropertySelect += MapPanelDocker_BezierLinePropertySelect;
mapPanelDocker.BlockPropertySelect += mapPanelDocker_BlockPropertySelect;
mapPanelDocker.IsLine = newType == NodeType.DirectLineCap; ;
mapPanelDocker.IsBezierLine = newType == NodeType.BezierLineCap;
InitialControlsOptions();
InitialTreeViewLayout();
}
#endregion
#region 初始化加载控件属性
private void InitialControlsOptions()
{
newType = NodeType.MousePick;
this.btn_鼠标.Enabled = false;
foreach (Control item in this.panel8.Controls)
{
if (item.GetType() == typeof(Button))
{
Button btn = (Button)item;
if (btn.Name.Contains("_"))
{
btn.Click += btnAll_Click;
}
}
}
}
#endregion
#region 鼠标箭头/站点、停车点......点击
private void btnAll_Click(object sender, EventArgs e)
{
foreach (Control item in this.panel8.Controls)
{
if (item.GetType() == typeof(Button))
{
Button btnTemp = (Button)item;
if (btnTemp.Name.Contains("_"))
{
btnTemp.Enabled = true;
}
}
}
Button btn = (Button)sender;
string strTemp = btn.Name.Split('_')[1];
switch (strTemp)
{
case "鼠标":
default:
newType = NodeType.MousePick;
this.btn_鼠标.Enabled = false;
break;
case "站点":
newType = NodeType.StationNode;
this.btn_站点.Enabled = false;
break;
case "停车点":
newType = NodeType.ParkingStationNode;
this.btn_停车点.Enabled = false;
break;
case "直线箭头":
newType = NodeType.DirectLineCap;
this.btn_直线箭头.Enabled = false;
break;
case "曲线箭头":
newType = NodeType.BezierLineCap;
this.btn_曲线箭头.Enabled = false;
break;
case "块":
newType = NodeType.Block;
break;
case "车":
newType = NodeType.Vehicle;
break;
}
mapPanelDocker.IsLine = newType == NodeType.DirectLineCap;
mapPanelDocker.IsBezierLine = newType == NodeType.BezierLineCap;
}
#endregion
#region 树状展开添加Layout
private void InitialTreeViewLayout()
{
this.treeviewLayout.Nodes.Clear();
TreeNode tn_origine = new TreeNode();
tn_origine.Text = "Layout VLayout-01";
tn_origine.ToolTipText = tn_origine.Text;
this.treeviewLayout.Nodes.Add(tn_origine);
AGV_Point[] allPoints = ReadXmlFile.ReadAllPoint(GlobalSystemConfig.Instance.AgvConfigPath);
if (allPoints != null)
{
#region 添加所有的点
TreeNode tn_sub = new TreeNode();
tn_sub.Text = "Points";
tn_sub.ToolTipText = tn_sub.Text;
tn_origine.Nodes.Add(tn_sub);
for (int i = 0; i < allPoints.Length; i++)
{
TreeNode tn_child = new TreeNode();
tn_child.Text = "Point " + allPoints[i]._Name;
tn_child.ToolTipText = tn_child.Text;
tn_sub.Nodes.Add(tn_child);//二级菜单
}
#endregion
}
AGV_Line[] allLines = ReadXmlFile.ReadAllLine(GlobalSystemConfig.Instance.AgvConfigPath);
if (allLines != null)
{
#region 添加所有的路径
TreeNode tn_sub = new TreeNode();
tn_sub.Text = "Paths";
tn_sub.ToolTipText = tn_sub.Text;
tn_origine.Nodes.Add(tn_sub);
for (int i = 0; i < allLines.Length; i++)
{
TreeNode tn_child = new TreeNode();
tn_child.Text = "Path " + allLines[i].LineName;
tn_child.ToolTipText = tn_child.Text;
tn_sub.Nodes.Add(tn_child);//二级菜单
}
#endregion
}
AGV_Block[] allBlocks = ReadXmlFile.ReadAllBlock(GlobalSystemConfig.Instance.AgvConfigPath);
if (allBlocks != null)
{
#region 添加所有的块
TreeNode tn_sub = new TreeNode();
tn_sub.Text = "Blocks";
tn_sub.ToolTipText = tn_sub.Text;
tn_origine.Nodes.Add(tn_sub);
for (int i = 0; i < allBlocks.Length; i++)
{
TreeNode tn_child = new TreeNode();
tn_child.Text = "Block " + allBlocks[i].BlockName;
tn_child.ToolTipText = tn_child.Text;
tn_child.ContextMenuStrip = this.menuBlock;
tn_sub.Nodes.Add(tn_child);//二级菜单
string[] strArr = allBlocks[i].menbers.Split(',');
for (int j = 0; j < strArr.Length; j++)
{
AGV_Line lineTemp = null;
for (int k = 0; k < allLines.Length; k++)
{
if (allLines[k].LineName == strArr[j])
{
lineTemp = allLines[k];
break;
}
}
if (lineTemp != null)
{
TreeNode tn_childchild = new TreeNode();
tn_childchild.Text = "Path " + lineTemp.LineName;
tn_childchild.ToolTipText = tn_childchild.Text;
tn_child.Nodes.Add(tn_childchild);//三级菜单
}
}
}
#endregion
}
this.treeViewVehicle.Nodes.Clear();
tn_origine = new TreeNode();
tn_origine.Text = "Layout Vehicles";
tn_origine.ToolTipText = tn_origine.Text;
this.treeViewVehicle.Nodes.Add(tn_origine);
mapPanelDocker.OpenMap(GlobalSystemConfig.Instance.AgvConfigPath);
this.treeviewLayout.ExpandAll();
this.treeViewVehicle.ExpandAll();
}
#region 添加子节点时
public void TreeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
Font rootFont = new Font("微软雅黑", 9F, FontStyle.Bold);
Font childFont = new Font("微软雅黑", 9F);
Brush foreBrush = new SolidBrush(Color.FromArgb(81, 81, 81));
Brush recBrush = new SolidBrush(Color.FromArgb(82, 218, 163));
Brush recSelectedBrush = new SolidBrush(Color.FromArgb(248, 248, 255));
Pen recPen = new Pen(new SolidBrush(Color.FromArgb(226, 226, 226)));
Pen recHoverPen = new Pen(new SolidBrush(Color.FromArgb(82, 218, 163)));
Pen linePen = new Pen(Color.Gray);
linePen.DashStyle = DashStyle.Dot;
Image icon;
if (e.Node.Level == 0)//根节点
{
#region 绘制根节点
icon = Resources.布局图;
if (e.Node.Text.Contains("Vehicles"))
{
icon = Resources.ziyuan;
}
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(227, 251, 244)), e.Bounds);
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 20, e.Node.Bounds.Y + 5);
e.Graphics.DrawString(e.Node.Text, rootFont, foreBrush, e.Node.Bounds.Left + 10, e.Node.Bounds.Top + 5);
#endregion
}
else if (e.Node.Level == 1)
{
#region 一级子节点
if (!e.Bounds.IsEmpty)
{
Point start = new Point(e.Node.Bounds.X, e.Node.Bounds.Y + 15);
Point middle = new Point(e.Node.Bounds.X - 30, e.Node.Bounds.Y + 15);
Point topEnd = new Point(e.Node.Bounds.X - 30, e.Node.Bounds.Y);
Point bottomEnd = new Point(e.Node.Bounds.X - 30, e.Node.Bounds.Y + 30);
e.Graphics.DrawLine(linePen, start, middle);
e.Graphics.DrawLine(linePen, middle, topEnd);
if (null != e.Node.NextNode)
{
e.Graphics.DrawLine(linePen, middle, bottomEnd);
}
#region 重绘图标
if (!e.Node.IsExpanded)
{
icon = Resources.plus;
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 25, e.Node.Bounds.Y + 8);
icon = Resources.wenjianjia__2_;
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 10, e.Node.Bounds.Y + 8);
}
else
{
icon = Resources.jianhao_1;
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 25, e.Node.Bounds.Y + 8);
icon = Resources.wenjianjia__2_;
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 10, e.Node.Bounds.Y + 8);
}
#endregion
Rectangle box = new Rectangle(e.Bounds.Left + 60, e.Bounds.Top + 4, this.Width - 60 - 25, e.Bounds.Height - 8);
if (e.Node.IsSelected)//二级节点被选中
{
e.Graphics.FillRectangle(recBrush, box);
}
e.Graphics.DrawString(e.Node.Text, childFont, foreBrush, e.Node.Bounds.Left + 15, e.Node.Bounds.Top + 6);
}
#endregion
}
else
{
#region 二级子节点
if (!e.Bounds.IsEmpty)
{
Point start = new Point(e.Node.Bounds.X + 5, e.Node.Bounds.Y + 15);
Point middle = new Point(e.Node.Bounds.X - 20, e.Node.Bounds.Y + 15);
Point topEnd = new Point(e.Node.Bounds.X - 20, e.Node.Bounds.Y);
Point bottomEnd = new Point(e.Node.Bounds.X - 20, e.Node.Bounds.Y + 30);
e.Graphics.DrawLine(linePen, middle, topEnd);//|
e.Graphics.DrawLine(linePen, start, middle);//--
if (null != e.Node.NextNode)
{
e.Graphics.DrawLine(linePen, middle, bottomEnd);
}
Rectangle box = new Rectangle(e.Bounds.Left + 65, e.Bounds.Top + 4, this.Width - 55 - 25, e.Bounds.Height - 8);
if (e.Node.Text.StartsWith("Point"))
{
icon = Resources.icon_test;
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 15, e.Node.Bounds.Y + 8);
}
else if (e.Node.Text.StartsWith("Path"))
{
icon = Resources.quxian;
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 15, e.Node.Bounds.Y + 8);
}
else if (e.Node.Text.StartsWith("Block"))
{
icon = Resources.icon_block;
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 15, e.Node.Bounds.Y + 8);
}
else if (e.Node.Text.StartsWith("Vehicle"))
{
icon = Resources.ziyuan;
e.Graphics.DrawImage(icon, e.Node.Bounds.X - 15, e.Node.Bounds.Y + 8);
}
if (e.Node.IsSelected)//二级节点被选中
{
e.Graphics.FillRectangle(recBrush, box);
e.Graphics.DrawString(e.Node.Text, childFont, recSelectedBrush, e.Node.Bounds.Left + 10, e.Node.Bounds.Top + 6);
}
else
{
if ((e.State & TreeNodeStates.Hot) != 0)//鼠标指针在二级节点上
{
e.Graphics.DrawRectangle(recHoverPen, box);
}
else
{
e.Graphics.DrawRectangle(recPen, box);
}
e.Graphics.DrawString(e.Node.Text, childFont, foreBrush, e.Node.Bounds.Left + 10, e.Node.Bounds.Top + 6);
}
}
#endregion
}
}
#endregion
#endregion
#region 画标尺和网格
/// <summary>
/// 画标尺和网格
/// </summary>
/// <param name="showRule"></param>
/// <param name="showNetLine"></param>
/// <returns></returns>
private Bitmap PaintRulesAndLine(bool showRule, bool showNetLine)
{
Bitmap bit = new Bitmap(this.Width * 4, this.Height * 4);
Graphics g = Graphics.FromImage(bit);
int widthInmm = bit.Width;
int heightInmm = bit.Height;
Pen p = new Pen(Color.Black, 1.5F);
if (showRule)
{
#region 绘制X轴标尺
for (int i = 0; i <= widthInmm / MonitorDPI * scaling; i++)//标尺总数
{
float x = MonitorDPI * scaling * i + AxisOffset;
PointF start = new PointF(x, AxisOffset);
PointF end = new PointF(x, AxisOffset - 3);
if (i % 5 == 0)
{
end = new PointF(x, AxisOffset - 6);
}
if (i % 10 == 0)
{
end = new PointF(x, AxisOffset - 13);
PointF pStrPoint = i == 0 ? new PointF(x - 3, AxisOffset - 25) : new PointF(x - 10, AxisOffset - 25);
g.DrawString((i * 100).ToString(), font, Brushes.Black, pStrPoint);
}
g.DrawLine(Pens.Black, start, end);
}
#endregion
Brush bBlack = Brushes.Black;
#region 绘制y轴标尺
for (int i = 0; i <= heightInmm / MonitorDPI * scaling; i++)
{
float y = MonitorDPI * scaling * i + AxisOffset;
PointF start = new PointF(AxisOffset, y);
PointF end = new PointF(AxisOffset - 3, y);
if (i % 5 == 0)
{
end = new PointF(AxisOffset - 6, y);
}
if (i % 10 == 0)
{
end = new PointF(AxisOffset - 12, y);
PointF pStrPoint = i == 0 ? new PointF(AxisOffset - 20, y - 5) : new PointF(AxisOffset - 32, y - 12);
g.DrawString((i * 100).ToString(), font, bBlack, pStrPoint);
}
g.DrawLine(Pens.Black, start, end);
}
#endregion
}
if (showNetLine)
{
#region 绘制网格
p = new Pen(Color.Gray, 1);
p.DashStyle = DashStyle.Dot;
for (int i = 0; i <= widthInmm / MonitorDPI; i++)//x方向网格
{
g.DrawLine(p, AxisOffset, ((float)(MonitorDPI * i * scaling) + AxisOffset), widthInmm, ((float)(MonitorDPI * i * scaling) + AxisOffset));
}
for (int i = 0; i <= widthInmm / MonitorDPI; i++)//y方向网格
{
g.DrawLine(p, ((float)(MonitorDPI * i * scaling) + AxisOffset), AxisOffset, ((float)(MonitorDPI * i * scaling) + AxisOffset), heightInmm);
}
#endregion
}
p = new Pen(Color.Black, 1);
g.DrawLine(p, new PointF(AxisOffset, AxisOffset), new PointF(widthInmm, AxisOffset));
g.DrawLine(p, new PointF(AxisOffset, AxisOffset), new PointF(AxisOffset, heightInmm));
return bit;
}
#endregion
#region 获得垂直的文本格式
private string GetVString(string inStr)
{
string retStr = "";
for (int i = 0; i < inStr.Length; i++)
{
retStr += inStr[i] + Environment.NewLine;
}
return retStr;
}
#endregion
#endregion
#region 窗体加载时
private void frm_AGVMain_Load(object sender, EventArgs e)
{
timer1.Start();
}
#endregion
#region 绑定对应的属性窗口
private void MapPanelDocker_CirclePropertySelect(MapNodeProperty mapStation)
{
propertyGridControl.SelectedObject = mapStation;
}
private void MapPanelDocker_LinePropertySelect(MapLineProperty mapLine)
{
propertyGridControl.SelectedObject = mapLine;
}
private void MapPanelDocker_BezierLinePropertySelect(MapBezierProperty mapBezierLine)
{
propertyGridControl.SelectedObject = mapBezierLine;
}
private void mapPanelDocker_BlockPropertySelect(MapBlockProperty mapBlock)
{
propertyGridControl.SelectedObject = mapBlock;
}
#endregion
#region 获取临近标尺内的网格点
public static Point GetNearRulePoint(Point p)
{
Point retP = p;
int x = p.X;
int y = p.Y;
int intTempx = (int)((x - AxisOffset) / MonitorDPI / scaling);//在第几个网格
int intTempy = (int)((y - AxisOffset) / MonitorDPI / scaling);//在第几个网格
int singleRuleNetWidth = (int)(MonitorDPI * scaling);
int locationX = AxisOffset + (int)((intTempx + 1) * MonitorDPI * scaling);
int locationX1 = AxisOffset + (int)((intTempx) * MonitorDPI * scaling);
int locationY = AxisOffset + (int)((intTempy + 1) * MonitorDPI * scaling);
int locationY1 = AxisOffset + (int)((intTempy) * MonitorDPI * scaling);
if (retP.X >= locationX1 + singleRuleNetWidth / 2)
{
retP.X = locationX;
}
else
{
retP.X = locationX1;
}
if (retP.Y >= locationY1 + singleRuleNetWidth / 2)
{
retP.Y = locationY;
}
else
{
retP.Y = locationY1;
}
return retP;
}
#endregion
#region 转换成模型坐标
/// <summary>
/// 转成模型坐标
/// </summary>
/// <param name="pSourceLocation"></param>
/// <returns></returns>
private Point GetInFactLocation(Point pSourceLocation)
{
int x = pSourceLocation.X;
int y = pSourceLocation.Y;
if (x >= AxisOffset && y >= AxisOffset)
{
x = (int)((x - AxisOffset) / MonitorDPI / scaling * 100);
y = (int)((y - AxisOffset) / MonitorDPI / scaling * 100);
}
Point pTemp = new Point(x, y);
return pTemp;
}
#endregion
#region 点击添加MapNode
private void mapPanel1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
if (newType == NodeType.StationNode)
{
#region 如果是站点
MapNode mapCircle = new MapNode();
mapPanelDocker.Controls.Add(mapCircle);
mapCircle.Name = "Point-" + GetMaxPointName();
mapCircle.NameText = mapCircle.Name;
mapCircle.OnNameChange += mapPanelDocker.mapCircle_OnNameChange;
mapCircle.Left = e.X;
mapCircle.Top = e.Y;
mapCircle.Size = new Size(20, 20);
mapCircle._type = "站点";
mapCircle.Click += mapPanelDocker.MapCircle_Click;
mapCircle.Focus();
Label label1 = new Label();
label1.BorderStyle = BorderStyle.None;
label1.Name = mapCircle.Name;
label1.BackColor = Color.Transparent;
label1.Location = new Point((mapCircle).Location.X - 15, (mapCircle).Location.Y - 12);
label1.ForeColor = mapPanelDocker.BackColor == Color.Black ? Color.White : Color.Black;
label1.Text = mapCircle.Name;
label1.AutoSize = true;
label1.Visible = true;
label1.BringToFront();
mapPanelDocker.Controls.Add(label1);
#endregion
}
else if (newType == NodeType.ParkingStationNode)
{
#region 停车点
MapNode mapCircle = new MapNode();
mapPanelDocker.Controls.Add(mapCircle);
mapCircle.Name = "Point-" + GetMaxPointName();
mapCircle.NameText = mapCircle.Name;
mapCircle.OnNameChange += mapPanelDocker.mapCircle_OnNameChange;
mapCircle.Left = e.X;
mapCircle.Top = e.Y;
mapCircle.Size = new Size(20, 20);
mapCircle._type = "停车点";
mapCircle.Click += mapPanelDocker.MapCircle_Click;
mapCircle.Focus();
Label label1 = new Label();
label1.BorderStyle = BorderStyle.None;
label1.Name = mapCircle.Name;
label1.BackColor = Color.Transparent;
label1.Location = new Point((mapCircle).Location.X - 15, (mapCircle).Location.Y - 12);
label1.ForeColor = mapPanelDocker.BackColor == Color.Black ? Color.White : Color.Black;
label1.Text = mapCircle.Name;
label1.AutoSize = true;
label1.Visible = true;
label1.BringToFront();
mapPanelDocker.Controls.Add(label1);
#endregion
}
else
{
propertyGridControl.SelectedObject = new MapPanelProperty((MapPanel)sender);
}
}
#endregion
#region 获得一个临时的最大的站点名称
/// <summary>
/// 获得一个临时的最大的站点数字编号
/// </summary>
/// <returns></returns>
private string GetMaxPointName()
{
List<string> pointListTemp = new List<string>();
foreach (Control item in this.mapPanelDocker.Controls)
{
if (item.GetType() == typeof(MapNode))
{
MapNode station = (MapNode)item;
string _Name = station.Name;
if (!pointListTemp.Contains(_Name))
{
pointListTemp.Add(_Name);
}
}
}
for (int i = 0; i < pointListTemp.Count; i++)
{
if (pointListTemp[i] == null)
{
pointListTemp.Remove(pointListTemp[i]);
}
}
if (pointListTemp.Count == 0)
{
return "001";
}
else if (pointListTemp.Count == 1 && pointListTemp[0] == "")
{
return "001";
}
else
{
string maxPoint = pointListTemp.OrderBy(a => a.ToString()).Max();
string strTemp = maxPoint.Split('-')[1];
int intTemp2 = int.Parse(strTemp);
return (intTemp2 + 1).ToString().PadLeft(3, '0');
}
}
#endregion
#region 获得一个最大的块的名称
public string GetMaxBlockName()
{
AGV_Block[] allBlocks = XmlHelper.ReadXmlFile.ReadAllBlock(GlobalSystemConfig.Instance.AgvConfigPath);
if (allBlocks != null && allBlocks.Length > 0)
{
string strTemp = allBlocks.Select(e => e.BlockName).Max();
if (strTemp != "")
{
int intTemp = int.Parse(strTemp.Replace("Block-", ""));
return (intTemp + 1).ToString().PadLeft(3, '0');
}
else
{
return "001";
}
}
return "001";
}
#endregion
#region 定时器主线程
private void timer1_Tick(object sender, EventArgs e)
{
#region 显示指针样式和时间
string temp = "";
switch (newType)
{
case NodeType.MousePick:
default:
temp = "鼠标";
break;
case NodeType.StationNode:
temp = "站点";
break;
case NodeType.ParkingStationNode:
temp = "停车点";
break;
case NodeType.DirectLineCap:
temp = "直线箭头";
break;
case NodeType.BezierLineCap:
temp = "曲线箭头";
break;
case NodeType.Block:
temp = "块";
break;
case NodeType.Vehicle:
temp = "车";
break;
}
this.lb_NewType.Text = "当前选项:" + temp;
this.lbTime.Text = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss(ddd)");
#endregion
}
#endregion
#region 窗体关闭时
private void frm_AGVMain_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dg = MessageBox.Show("Do you want to exit this Application?", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (dg == DialogResult.OK)
{
try
{
timer1.Stop();
}
catch
{
}
finally
{
loadForm = new LoadingForm();
loadForm.ShowLoadingDealy(2);
Application.ExitThread();
Application.Exit();//通知winform消息循环退出 在所有前台线程退出后退出应用 先停止线程 再终止线程
Environment.Exit(1);//直接终止所有线程,code为1即使有错误也直接终止 直接终止线程
}
}
else
{
e.Cancel = true;
}
}
#endregion
#region 打开配置文件
private void btn_打开文件_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = @"*.xml|*.xml";
openFileDialog.InitialDirectory = GlobalSystemConfig.Instance.AppStartPath + @"\AppConfigDir\";
if (openFileDialog.ShowDialog() == DialogResult.Cancel)
{
return;
}
mapPanelDocker.OpenMap(openFileDialog.FileName);
GlobalSystemConfig.Instance.AgvConfigPath = openFileDialog.FileName;
InitialTreeViewLayout();
floydCurrent = new FloydHelper();
}
#endregion
#region 保存数据到xml文件
private void bnt_保存_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = @"*.xml|*.xml";
saveFileDialog.InitialDirectory = GlobalSystemConfig.Instance.AppStartPath + @"\AppConfigDir\";
if (saveFileDialog.ShowDialog() == DialogResult.Cancel)
{
return;
}
mapPanelDocker.SaveMap(saveFileDialog.FileName);
XmlHelper.WriteXmlFile.UpdateModifiedDate(saveFileDialog.FileName);
floydCurrent = new FloydHelper();
}
#endregion
#region 上下左右
private void btn_Left_Click(object sender, EventArgs e)
{
this.mapPanelDocker.Focus();
this.btn_Left.Enabled = false;
SendKeys.Send("{LEFT}");
this.btn_Left.Enabled = true;
}
private void btn_up_Click(object sender, EventArgs e)
{
this.mapPanelDocker.Focus();
this.btn_Left.Enabled = false;
SendKeys.Send("{UP}");
this.btn_Left.Enabled = true;
}
private void button4_Click(object sender, EventArgs e)
{
this.mapPanelDocker.Focus();
this.btn_Left.Enabled = false;
SendKeys.Send("{DOWN}");
this.btn_Left.Enabled = true;
}
private void btn_right_Click(object sender, EventArgs e)
{
this.mapPanelDocker.Focus();
this.btn_Left.Enabled = false;
SendKeys.Send("{RIGHT}");
this.btn_Left.Enabled = true;
}
#endregion
#region 鼠标移入移出显示坐标
private void mapPanelDocker_MouseMove(object sender, MouseEventArgs e)
{
this.lbLocation.Text = "X:" + e.Location.X.ToString() + "、Y:" + e.Location.Y.ToString();
}
private void mapPanelDocker_MouseLeave(object sender, EventArgs e)
{
this.lbLocation.Text = "";
}
#endregion
#region treeView选中某一项时
private void treeviewLayout_AfterSelect(object sender, TreeViewEventArgs e)
{
TreeNode tn = e.Node;
if (tn != null)
{
if (tn.Text != "")
{
if (tn.Text.StartsWith("Path"))
{
this.mapPanelDocker.AddSelectLine(tn.Text);
}
else if (tn.Text.StartsWith("Point"))
{
this.mapPanelDocker.AddSelectStation(tn.Text);
}
else if (tn.Text.StartsWith("Block"))
{
this.mapPanelDocker.AddSelectBlck(tn.Text);
}
}
}
}
#endregion
#region 添加或者删除一条路径到Block
#region 添加
private void addToolStripMenuItem_Click(object sender, EventArgs e)
{
if (mapPanelDocker.SelectMapline != null || mapPanelDocker.SelectMapBezierline != null)
{
string strBlockName = this.treeviewLayout.SelectedNode.Text.Replace(" ", "").Replace("BlockBlock", "Block");
string lineName = "";
string BezierLineName = "";
if (mapPanelDocker.SelectMapline != null)
{
lineName = mapPanelDocker.SelectMapline.LineName;
}
if (mapPanelDocker.SelectMapBezierline != null)
{
BezierLineName = mapPanelDocker.SelectMapBezierline.LineName;
}
AGV_Block[] allBlocks = ReadXmlFile.ReadAllBlock(GlobalSystemConfig.Instance.AgvConfigPath);
for (int i = 0; i < allBlocks.Length; i++)
{
if (allBlocks[i].BlockName == strBlockName)
{
if (lineName != "")
{
if (!allBlocks[i].menbers.Contains(lineName))
{
if (allBlocks[i].menbers == "")
{
allBlocks[i].menbers = lineName;
}
else
{
allBlocks[i].menbers = allBlocks[i].menbers + "," + lineName;
}
}
}
if (BezierLineName != "")
{
if (!allBlocks[i].menbers.Contains(BezierLineName))
{
if (allBlocks[i].menbers == "")
{
allBlocks[i].menbers = BezierLineName;
}
else
{
allBlocks[i].menbers = allBlocks[i].menbers + "," + BezierLineName;
}
}
}
XmlHelper.WriteXmlFile.WriteOrCreateBlockValue(allBlocks[i], GlobalSystemConfig.Instance.AgvConfigPath);
InitialTreeViewLayout();
}
}
}
}
#endregion
#region 移除
private void deleteSelectPathToBlocksToolStripMenuItem_Click(object sender, EventArgs e)
{
if (mapPanelDocker.SelectMapline != null || mapPanelDocker.SelectMapBezierline != null)
{
string strBlockName = this.treeviewLayout.SelectedNode.Text.Replace(" ", "").Replace("BlockBlock", "Block");
string lineName = "";
string BezierLineName = "";
if (mapPanelDocker.SelectMapline != null)
{
lineName = mapPanelDocker.SelectMapline.LineName;
}
if (mapPanelDocker.SelectMapBezierline != null)
{
BezierLineName = mapPanelDocker.SelectMapBezierline.LineName;
}
AGV_Block[] allBlocks = ReadXmlFile.ReadAllBlock(GlobalSystemConfig.Instance.AgvConfigPath);
for (int i = 0; i < allBlocks.Length; i++)
{
if (allBlocks[i].BlockName == strBlockName)
{
if (lineName != "")
{
if (allBlocks[i].menbers.Contains(lineName))
{
if (allBlocks[i].menbers == lineName)
{
allBlocks[i].menbers = "";
}
else if (allBlocks[i].menbers.Contains(lineName + ","))
{
allBlocks[i].menbers = allBlocks[i].menbers.Replace(lineName + ",", "");
}
else
{
allBlocks[i].menbers = allBlocks[i].menbers.Replace(lineName, "");
}
}
}
if (BezierLineName != "")
{
if (allBlocks[i].menbers.Contains(BezierLineName))
{
if (allBlocks[i].menbers == BezierLineName)
{
allBlocks[i].menbers = "";
}
else if (allBlocks[i].menbers.Contains(BezierLineName + ","))
{
allBlocks[i].menbers = allBlocks[i].menbers.Replace(BezierLineName + ",", "");
}
else
{
allBlocks[i].menbers = allBlocks[i].menbers.Replace(BezierLineName, "");
}
}
}
XmlHelper.WriteXmlFile.WriteOrCreateBlockValue(allBlocks[i], GlobalSystemConfig.Instance.AgvConfigPath);
InitialTreeViewLayout();
}
}
}
}
#endregion
#region 删除整个块
private void deleteEntileBlocksToolStripMenuItem_Click(object sender, EventArgs e)
{
string strBlockName = this.treeviewLayout.SelectedNode.Text.Replace(" ", "").Replace("BlockBlock", "Block");
if (strBlockName.StartsWith("Block"))
{
if (mapPanelDocker.ListMapBlock != null && mapPanelDocker.ListMapBlock.Count > 0)
{
for (int i = 0; i < mapPanelDocker.ListMapBlock.Count; i++)
{
if (mapPanelDocker.ListMapBlock[i].BlockName == strBlockName)
{
mapPanelDocker.ListMapBlock.Remove(mapPanelDocker.ListMapBlock[i]);
mapPanelDocker.SaveMap(GlobalSystemConfig.Instance.AgvConfigPath);
InitialTreeViewLayout();
}
}
}
}
}
#endregion
#endregion
#region 右键菜单打开时
private void menuBlock_Opening(object sender, CancelEventArgs e)
{
}
#endregion
#region 点击进行选中当前节点
private void treeviewLayout_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
{
this.treeviewLayout.SelectedNode = e.Node;
}
}
#endregion
#region 块点击事件
private void btn_块_Click(object sender, EventArgs e)
{
if (newType == NodeType.Block)
{
MapBlock block = new MapBlock();
block.OnColorChange += mapPanelDocker.block_OnColorChange;
block.BlockName = "Block-" + GetMaxBlockName();
block.BlockColor = Color.Red;
block.menberLines = new List<MapLine>();
block.menberBezierLines = new List<MapBezierLine>();
block.isSlected = true;
mapPanelDocker.ListMapBlock.Add(block);
mapPanelDocker.SaveMap(GlobalSystemConfig.Instance.AgvConfigPath);
}
InitialTreeViewLayout();
}
#endregion
#region 双击查找路径或者站点
private void treeviewLayout_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
string whichText = e.Node.Text.Replace(" ", "");
if (whichText.StartsWith("PointPoint") || whichText.StartsWith("PathPoint"))
{
AGV_Line[] allLines = XmlHelper.ReadXmlFile.ReadAllLine(GlobalSystemConfig.Instance.AgvConfigPath);
if (whichText.StartsWith("PointPoint"))
{
whichText = whichText.Replace("PointPoint", "Point").Replace("PathPoint", "Point");//点
foreach (Control item in mapPanelDocker.Controls)
{
if(item.GetType()==typeof(MapNode))
{
MapNode node = (MapNode)item;
if(node.Name==whichText)
{
Graphics g = mapPanelDocker.CreateGraphics();
g.SmoothingMode = SmoothingMode.HighQuality;
Pen p = new Pen(Color.Lime, 2);
Point pointTemp = new Point(node.Location.X - 25, node.Location.Y - 25);
Size sizeTemp = new Size(70, 70);
g.DrawEllipse(p, pointTemp.X, pointTemp.Y, sizeTemp.Width, sizeTemp.Height);
}
}
}
}
else
{
whichText = whichText.Replace("PointPoint", "Point").Replace("PathPoint", "Point");//路径
if (allLines != null && allLines.Length > 0)
{
for (int i = 0; i < allLines.Length; i++)
{
if (allLines[i].LineName == whichText)
{
AGV_Line agvLine = allLines[i];
Pen p = new Pen(Color.Red, 2);
Graphics g = mapPanelDocker.CreateGraphics();
g.SmoothingMode = SmoothingMode.HighQuality;
if (agvLine.controlPoint1.X != 0)
{
Point pointTemp = new Point(((agvLine.controlPoint1.X + agvLine.controlPoint2.X) / 2) - 20, ((agvLine.controlPoint1.Y + agvLine.controlPoint2.Y) / 2) - 20);
Size sizeTemp = new Size(60, 60);
g.DrawEllipse(p, pointTemp.X, pointTemp.Y, sizeTemp.Width, sizeTemp.Height);
}
else
{
Point pointTemp1 = new Point(0,0);
Point pointTemp2 = new Point(0, 0);
foreach (Control item in mapPanelDocker.Controls)
{
if (item.GetType() == typeof(MapNode))
{
MapNode node = (MapNode)item;
if (node.Name == agvLine.StartControl)
{
pointTemp1 = node.Location;
}
if (node.Name == agvLine.EndControl)
{
pointTemp2 = node.Location;
}
}
}
if (pointTemp1.X != 0 && pointTemp2.X != 0)
{
Point pointTemp = new Point(((pointTemp1.X + pointTemp2.X) / 2) - 20, ((pointTemp1.Y + pointTemp2.Y) / 2) - 20);
Size sizeTemp = new Size(60, 60);
g.DrawEllipse(p, pointTemp.X, pointTemp.Y, sizeTemp.Width, sizeTemp.Height);
}
}
}
}
}
}
}
}
#endregion
#region 新建一个地图文件
private void btn_New_Click(object sender, EventArgs e)
{
mapPanelDocker.OpenMap("");
GlobalSystemConfig.Instance.AgvConfigPath = "";
InitialTreeViewLayout();
floydCurrent = new FloydHelper();
}
#endregion
#region 车点击事件
private void btn_车_Click(object sender, EventArgs e)
{
if (newType == NodeType.Vehicle)
{
MapBlock block = new MapBlock();
block.OnColorChange += mapPanelDocker.block_OnColorChange;
block.BlockName = "Vehicle-" + GetMaxBlockName();
block.BlockColor = Color.Red;
block.menberLines = new List<MapLine>();
block.menberBezierLines = new List<MapBezierLine>();
block.isSlected = true;
mapPanelDocker.ListMapBlock.Add(block);
mapPanelDocker.SaveMap(GlobalSystemConfig.Instance.AgvConfigPath);
}
InitialTreeViewLayout();
}
#endregion
#region 双击时
private void treeViewVehicle_AfterSelect(object sender, TreeViewEventArgs e)
{
}
#endregion
#region 双击时将当前小车进行标定
private void treeViewVehicle_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
}
#endregion
#region 鼠标左键或者有键将当前节点选中
private void treeViewVehicle_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
{
this.treeViewVehicle.SelectedNode = e.Node;
}
}
#endregion
#region 是否显示站点的label
bool showLabelFlag = true;
private void button2_Click(object sender, EventArgs e)
{
if (showLabelFlag)
{
this.btn_ShowLabel.BackColor = Color.Transparent;
showLabelFlag = false;
foreach (Control item in this.mapPanelDocker.Controls)
{
if (item.GetType() == typeof(Label))
{
item.Text = "";
}
}
}
else
{
this.btn_ShowLabel.BackColor = Color.Wheat;
showLabelFlag = true;
foreach (Control item in this.mapPanelDocker.Controls)
{
if (item.GetType() == typeof(Label))
{
item.Text = item.Name;
}
}
}
this.mapPanelDocker.Invalidate();
}
#endregion
#region 是否显示块的背景颜色
bool showBlockLine = true;
private void button1_Click(object sender, EventArgs e)
{
if (showBlockLine)
{
this.btn_ShowBlock.BackColor = Color.Wheat;
showBlockLine = false;
foreach (MapBlock item in this.mapPanelDocker.ListMapBlock)
{
item.ShowBlockLineColor = false;
}
}
else
{
this.btn_ShowBlock.BackColor = Color.Transparent;
showBlockLine = true;
foreach (MapBlock item in this.mapPanelDocker.ListMapBlock)
{
item.ShowBlockLineColor = true;
}
}
this.mapPanelDocker.Invalidate();
}
#endregion
private void btn_查找小车_Click(object sender, EventArgs e)
{
}
#region 显示当前地图的版本信息
private void showToolStripMenuItem_Click(object sender, EventArgs e)
{
string filePath = GlobalSystemConfig.Instance.AgvConfigPath;
string StationNum, ParkingNum, DirectNum,
BezierNum, FileName, BlockNum,
VehicleNum, ModifyDate;
ReadXmlFile.GetMapNodeNum(out StationNum, out ParkingNum, out DirectNum,
out BezierNum, out FileName, out BlockNum,
out VehicleNum, out ModifyDate, filePath);
NumberModel model = new NumberModel()
{
StationNum = StationNum,
ParkingStationnum = ParkingNum,
DirectLineNum = DirectNum,
BezierLineNum = BezierNum,
FileName = FileName,
BlockNum = BlockNum,
VehicleNum = VehicleNum,
ModifiedDate = ModifyDate
};
frm_Property = new frm_ModelProperty(model);
frm_Property.ShowDialog();
}
#endregion