From 5ec9a64b9ecfb1bac29f144c83db7be3b6ae7a2c Mon Sep 17 00:00:00 2001
From: "xhm\\HP" <1173131411@qq.com>
Date: Sun, 16 Mar 2025 13:14:05 +0800
Subject: [PATCH] =?UTF-8?q?=E7=95=8C=E9=9D=A2=E4=B8=AD=E5=A4=84=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 DH.Devices.Vision/DH.Devices.Vision.csproj    |   1 +
 DH.Devices.Vision/DetectionConfig.cs          | 211 +++++-
 DH.Devices.Vision/SimboVisionMLBase.cs        |  29 +-
 DHSoftware/DHSoftware.csproj                  |  12 +-
 DHSoftware/EnumHelper.cs                      |  16 +
 DHSoftware/MainWindow.Designer.cs             |   2 +-
 DHSoftware/MainWindow.cs                      |   5 +-
 DHSoftware/MainWindow.resx                    |   4 +-
 DHSoftware/Views/AddCameraWindow.Designer.cs  |  81 +++
 DHSoftware/Views/AddCameraWindow.cs           |  61 ++
 DHSoftware/Views/AddCameraWindow.resx         | 120 ++++
 DHSoftware/Views/AddCubicleWindow.Designer.cs |  82 +++
 DHSoftware/Views/AddCubicleWindow.cs          |  55 ++
 DHSoftware/Views/AddCubicleWindow.resx        | 120 ++++
 .../Views/CorrelatedCameraEdit.Designer.cs    | 149 +++++
 DHSoftware/Views/CorrelatedCameraEdit.cs      | 121 ++++
 DHSoftware/Views/CorrelatedCameraEdit.resx    | 120 ++++
 DHSoftware/Views/DetectConfigControl.cs       |   4 +
 DHSoftware/Views/DetectControl.Designer.cs    | 607 ++++++++++++++++++
 DHSoftware/Views/DetectControl.cs             | 480 ++++++++++++++
 DHSoftware/Views/DetectControl.resx           | 150 +++++
 .../Views/DetectionLableEdit.Designer.cs      | 290 +++++++++
 DHSoftware/Views/DetectionLableEdit.cs        |  95 +++
 DHSoftware/Views/DetectionLableEdit.resx      | 120 ++++
 DHSoftware/Views/PreTreatEdit.Designer.cs     | 167 +++++
 DHSoftware/Views/PreTreatEdit.cs              |  57 ++
 DHSoftware/Views/PreTreatEdit.resx            | 120 ++++
 .../Views/PreTreatUserControl.Designer.cs     |   1 +
 DHSoftware/Views/PreTreatUserControl.cs       |   5 +
 DHSoftware/Views/PreTreatUserControl.resx     |   4 +-
 DHSoftware/Views/SettingWindow.Designer.cs    | 138 ++++
 DHSoftware/Views/SettingWindow.cs             | 135 ++++
 DHSoftware/Views/SettingWindow.resx           | 120 ++++
 DHSoftware/Views/SettingWindow1.Designer.cs   | 181 ++++++
 DHSoftware/Views/SettingWindow1.cs            | 188 ++++++
 DHSoftware/Views/SettingWindow1.resx          | 120 ++++
 DHSoftware/Views/UserConfigFrm.resx           |   4 +-
 DHSoftware/Views/​MotionControl.Designer.cs    |  44 ++
 DHSoftware/Views/​MotionControl.cs             |  20 +
 DHSoftware/Views/​MotionControl.resx           | 120 ++++
 40 files changed, 4317 insertions(+), 42 deletions(-)
 create mode 100644 DHSoftware/Views/AddCameraWindow.Designer.cs
 create mode 100644 DHSoftware/Views/AddCameraWindow.cs
 create mode 100644 DHSoftware/Views/AddCameraWindow.resx
 create mode 100644 DHSoftware/Views/AddCubicleWindow.Designer.cs
 create mode 100644 DHSoftware/Views/AddCubicleWindow.cs
 create mode 100644 DHSoftware/Views/AddCubicleWindow.resx
 create mode 100644 DHSoftware/Views/CorrelatedCameraEdit.Designer.cs
 create mode 100644 DHSoftware/Views/CorrelatedCameraEdit.cs
 create mode 100644 DHSoftware/Views/CorrelatedCameraEdit.resx
 create mode 100644 DHSoftware/Views/DetectControl.Designer.cs
 create mode 100644 DHSoftware/Views/DetectControl.cs
 create mode 100644 DHSoftware/Views/DetectControl.resx
 create mode 100644 DHSoftware/Views/DetectionLableEdit.Designer.cs
 create mode 100644 DHSoftware/Views/DetectionLableEdit.cs
 create mode 100644 DHSoftware/Views/DetectionLableEdit.resx
 create mode 100644 DHSoftware/Views/PreTreatEdit.Designer.cs
 create mode 100644 DHSoftware/Views/PreTreatEdit.cs
 create mode 100644 DHSoftware/Views/PreTreatEdit.resx
 create mode 100644 DHSoftware/Views/SettingWindow.Designer.cs
 create mode 100644 DHSoftware/Views/SettingWindow.cs
 create mode 100644 DHSoftware/Views/SettingWindow.resx
 create mode 100644 DHSoftware/Views/SettingWindow1.Designer.cs
 create mode 100644 DHSoftware/Views/SettingWindow1.cs
 create mode 100644 DHSoftware/Views/SettingWindow1.resx
 create mode 100644 DHSoftware/Views/​MotionControl.Designer.cs
 create mode 100644 DHSoftware/Views/​MotionControl.cs
 create mode 100644 DHSoftware/Views/​MotionControl.resx

diff --git a/DH.Devices.Vision/DH.Devices.Vision.csproj b/DH.Devices.Vision/DH.Devices.Vision.csproj
index 6ca65e5..9d567ff 100644
--- a/DH.Devices.Vision/DH.Devices.Vision.csproj
+++ b/DH.Devices.Vision/DH.Devices.Vision.csproj
@@ -16,6 +16,7 @@
 
 
   <ItemGroup>
+    <PackageReference Include="AntdUI" Version="1.8.9" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
     <PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
     <PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
diff --git a/DH.Devices.Vision/DetectionConfig.cs b/DH.Devices.Vision/DetectionConfig.cs
index 90afdb6..38737af 100644
--- a/DH.Devices.Vision/DetectionConfig.cs
+++ b/DH.Devices.Vision/DetectionConfig.cs
@@ -5,6 +5,7 @@ using static OpenCvSharp.AgastFeatureDetector;
 using System.Text.RegularExpressions;
 using System.Text;
 using System.Drawing.Design;
+using AntdUI;
 
 namespace DH.Devices.Vision
 {
@@ -255,24 +256,33 @@ namespace DH.Devices.Vision
         }
        
     }
-    public class RelatedCamera 
+    public class RelatedCamera : NotifyProperty
     {
 
+        private string _cameraSourceId = "";
         [Category("关联相机")]
-        [DisplayName("关联相机")]
-        [Description("关联相机描述")]
-       
+        [DisplayName("相机源ID")]
+        [Description("关联相机的唯一标识符")]
         //[TypeConverter(typeof(CollectionCountConvert))]
-        public string CameraSourceId { get; set; } = "";
+        public string CameraSourceId
+        {
+            get { return _cameraSourceId; }
+            set
+            {
+                if (_cameraSourceId == value) return;
+                _cameraSourceId = value;
+                OnPropertyChanged(nameof(CameraSourceId));
+            }
+        }
 
         public RelatedCamera()
         {
-
         }
+
+        // 可选:添加带 Selected 的构造函数
         public RelatedCamera(string cameraSourceId)
         {
             CameraSourceId = cameraSourceId;
-
         }
     }
     public class DetectionConfig
@@ -299,6 +309,8 @@ namespace DH.Devices.Vision
         [Description("关联相机描述")]
         //[TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
        
+
+
         public List<RelatedCamera> CameraCollects { get; set; } = new List<RelatedCamera>();
 
 
@@ -400,10 +412,15 @@ namespace DH.Devices.Vision
         
         public List<DetectionFilter> DetectionFilterList { get; set; } = new List<DetectionFilter>();
 
+
+        /// <summary>
+        /// 标签集合
+        /// </summary>
+        public List<DetectionLable> DetectionLableList { get; set; } = new List<DetectionLable>();
         //[Category("深度学习配置")]
         //[DisplayName("检测配置标签")]
         //[Description("检测配置标签关联")]
-      
+
         //public List<DetectConfigLabel> DetectConfigLabelList { get; set; } = new List<DetectConfigLabel>();
 
 
@@ -423,6 +440,184 @@ namespace DH.Devices.Vision
 
         }
     }
+
+    //大改预处理类
+    /// <summary>
+    /// 预处理
+    /// </summary>
+    public class PreTreatParam : NotifyProperty
+    {
+
+
+        private bool _selected = false;
+        public bool Selected
+        {
+            get { return _selected; }
+            set
+            {
+                if (_selected == value) return;
+                _selected = value;
+                OnPropertyChanged(nameof(Selected));
+            }
+        }
+        private string _name;
+        public string Name
+        {
+            get { return _name; }
+            set
+            {
+                if (_name == value) return;
+                _name = value;
+                OnPropertyChanged(nameof(Name));
+            }
+        }
+
+
+        private string _value;
+        public string Value
+        {
+            get { return _value; }
+            set
+            {
+                if (_value == value) return;
+                _value = value;
+                OnPropertyChanged(nameof(Value));
+            }
+        }
+
+        private CellLink[] cellLinks;
+        public CellLink[] CellLinks
+        {
+            get { return cellLinks; }
+            set
+            {
+                if (cellLinks == value) return;
+                cellLinks = value;
+                OnPropertyChanged(nameof(CellLinks));
+            }
+        }
+
+
+    }
+
+
+    public class DetectionLable : NotifyProperty
+    {
+        private bool _selected = false;
+        private string _labelId;
+        private string _labelName;
+        private double _maxSource;
+        private double _minSource;
+        private double _maxArea;
+        private double _minArea;
+        private ResultState _resultState = ResultState.ResultTBD;
+
+
+
+   
+        public bool Selected
+        {
+            get { return _selected; }
+            set
+            {
+                if (_selected == value) return;
+                _selected = value;
+                OnPropertyChanged(nameof(Selected));
+            }
+        }
+
+
+        public string LabelId
+        {
+            get { return _labelId; }
+            set
+            {
+                if (_labelId == value) return;
+                _labelId = value;
+                OnPropertyChanged(nameof(LabelId));
+            }
+        }
+
+        public string LabelName
+        {
+            get { return _labelName; }
+            set
+            {
+                if (_labelName == value) return;
+                _labelName = value;
+                OnPropertyChanged(nameof(LabelName));
+            }
+        }
+
+        public double MaxSource
+        {
+            get { return _maxSource; }
+            set
+            {
+                if (_maxSource.Equals(value)) return;
+                _maxSource = value;
+                OnPropertyChanged(nameof(MaxSource));
+            }
+        }
+
+        public double MinSource
+        {
+            get { return _minSource; }
+            set
+            {
+                if (_minSource.Equals(value)) return;
+                _minSource = value;
+                OnPropertyChanged(nameof(MinSource));
+            }
+        }
+
+        public double MaxArea
+        {
+            get { return _maxArea; }
+            set
+            {
+                if (_maxArea.Equals(value)) return;
+                _maxArea = value;
+                OnPropertyChanged(nameof(MaxArea));
+            }
+        }
+
+        public double MinArea
+        {
+            get { return _minArea; }
+            set
+            {
+                if (_minArea.Equals(value)) return;
+                _minArea = value;
+                OnPropertyChanged(nameof(MinArea));
+            }
+        }
+
+        public ResultState ResultState
+        {
+            get { return _resultState; }
+            set
+            {
+                if (_resultState == value) return;
+                _resultState = value;
+                OnPropertyChanged(nameof(ResultState));
+            }
+        }
+
+        private CellLink[] cellLinks;
+        public CellLink[] CellLinks
+        {
+            get { return cellLinks; }
+            set
+            {
+                if (cellLinks == value) return;
+                cellLinks = value;
+                OnPropertyChanged(nameof(CellLinks));
+            }
+        }
+    }
+
+
     /// <summary>
     /// 识别目标定义 class:分类信息    Detection Segmentation:要识别的对象
     /// </summary>
diff --git a/DH.Devices.Vision/SimboVisionMLBase.cs b/DH.Devices.Vision/SimboVisionMLBase.cs
index 485093e..ed6bb6c 100644
--- a/DH.Devices.Vision/SimboVisionMLBase.cs
+++ b/DH.Devices.Vision/SimboVisionMLBase.cs
@@ -1,10 +1,13 @@
-
+using AntdUI;
+
 using OpenCvSharp;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Drawing;
 using System.Runtime.InteropServices;
+using System.Xml.Linq;
+using static System.ComponentModel.Design.ObjectSelectorEditor;
 
 namespace DH.Devices.Vision
 {
@@ -87,30 +90,8 @@ namespace DH.Devices.Vision
         }
 
     }
-    public class PreTreatParam 
-    {
 
-        /// <summary>
-        /// 参数名称
-        /// </summary>
-        ///     
-        [Category("预处理参数")]
-        [DisplayName("参数名称")]
-        [Description("参数名称")]
-        public string Name { get; set; }
-
-
-        /// <summary>
-        /// 参数值
-        /// </summary>
-        ///     
-        [Category("预处理参数")]
-        [DisplayName("参数值")]
-        [Description("参数值")]
-        public string Value { get; set; }
-
-       
-    }
+ 
     public static class MLGPUEngine
     {
 
diff --git a/DHSoftware/DHSoftware.csproj b/DHSoftware/DHSoftware.csproj
index 073fe36..6fe46fa 100644
--- a/DHSoftware/DHSoftware.csproj
+++ b/DHSoftware/DHSoftware.csproj
@@ -16,9 +16,19 @@
 
 
 
+	
+
+	
+
+
+
+
+
+
+
 
   <ItemGroup>
-    <PackageReference Include="AntdUI" Version="1.9.3" />
+    <PackageReference Include="AntdUI" Version="1.8.9" />
     <PackageReference Include="System.IO.Ports" Version="9.0.2" />
   </ItemGroup>
 
diff --git a/DHSoftware/EnumHelper.cs b/DHSoftware/EnumHelper.cs
index be03c71..06d359b 100644
--- a/DHSoftware/EnumHelper.cs
+++ b/DHSoftware/EnumHelper.cs
@@ -48,5 +48,21 @@ namespace DHSoftware
                 return enumObj.ToString();
             }
         }
+
+        // 根据描述获取枚举值(泛型方法)
+        public static T GetEnumFromDescription<T>(string description) where T : Enum
+        {
+            Type enumType = typeof(T);
+            foreach (T value in Enum.GetValues(enumType))
+            {
+                string desc = GetEnumDescription(value);
+                if (desc == description)
+                {
+                    return value;
+                }
+            }
+            throw new ArgumentException($"在枚举 {enumType.Name} 中未找到描述为 '{description}' 的值");
+        }
+
     }
 }
diff --git a/DHSoftware/MainWindow.Designer.cs b/DHSoftware/MainWindow.Designer.cs
index b2b9275..5ee2d61 100644
--- a/DHSoftware/MainWindow.Designer.cs
+++ b/DHSoftware/MainWindow.Designer.cs
@@ -142,7 +142,7 @@
             // label1
             // 
             label1.AutoSize = true;
-            label1.Location = new Point(709, 10);
+            label1.Location = new Point(817, 10);
             label1.Name = "label1";
             label1.Size = new Size(64, 21);
             label1.TabIndex = 1;
diff --git a/DHSoftware/MainWindow.cs b/DHSoftware/MainWindow.cs
index 673471c..356f422 100644
--- a/DHSoftware/MainWindow.cs
+++ b/DHSoftware/MainWindow.cs
@@ -1496,9 +1496,10 @@ namespace DHSoftware
         private void HandleSettingsButton()
         {
             // Add the code for the "设置" button click here
-            MessageBox.Show("设置按钮按下");
-
+            //MessageBox.Show("设置按钮按下");
 
+            SettingWindow1 settingWindow = new SettingWindow1();
+            settingWindow.Show();
         }
 
         private void HandleLoginButton()
diff --git a/DHSoftware/MainWindow.resx b/DHSoftware/MainWindow.resx
index 3511979..1e30dff 100644
--- a/DHSoftware/MainWindow.resx
+++ b/DHSoftware/MainWindow.resx
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <root>
   <!--
-    Microsoft ResX Schema 
+    Microsoft ResX Schema
 
     Version 2.0
 
@@ -48,7 +48,7 @@
     value   : The object must be serialized with
             : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
-    
+
     mimetype: application/x-microsoft.net.object.soap.base64
     value   : The object must be serialized with
             : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
diff --git a/DHSoftware/Views/AddCameraWindow.Designer.cs b/DHSoftware/Views/AddCameraWindow.Designer.cs
new file mode 100644
index 0000000..8ef3df1
--- /dev/null
+++ b/DHSoftware/Views/AddCameraWindow.Designer.cs
@@ -0,0 +1,81 @@
+namespace DHSoftware.Views
+{
+    partial class AddCameraWindow
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            btnOK = new AntdUI.Button();
+            btnCancel = new AntdUI.Button();
+            stName = new AntdUI.Select();
+            SuspendLayout();
+            // 
+            // btnOK
+            // 
+            btnOK.Location = new Point(170, 136);
+            btnOK.Name = "btnOK";
+            btnOK.Size = new Size(75, 40);
+            btnOK.TabIndex = 1;
+            btnOK.Text = "确定";
+            btnOK.Click += btnOK_Click;
+            // 
+            // btnCancel
+            // 
+            btnCancel.Location = new Point(259, 136);
+            btnCancel.Name = "btnCancel";
+            btnCancel.Size = new Size(75, 40);
+            btnCancel.TabIndex = 2;
+            btnCancel.Text = "取消";
+            btnCancel.Click += btnCancel_Click;
+            // 
+            // stName
+            // 
+            stName.Location = new Point(39, 46);
+            stName.Name = "stName";
+            stName.PlaceholderText = "请选择关联相机";
+            stName.Size = new Size(281, 50);
+            stName.TabIndex = 3;
+            // 
+            // AddCameraWindow
+            // 
+            AutoScaleDimensions = new SizeF(7F, 17F);
+            AutoScaleMode = AutoScaleMode.Font;
+            ClientSize = new Size(369, 188);
+            Controls.Add(stName);
+            Controls.Add(btnCancel);
+            Controls.Add(btnOK);
+            Name = "AddCameraWindow";
+            StartPosition = FormStartPosition.CenterParent;
+            Text = "AddCubicleWindow";
+            ResumeLayout(false);
+        }
+
+        #endregion
+        private AntdUI.Button btnOK;
+        private AntdUI.Button btnCancel;
+        private AntdUI.Select stName;
+    }
+}
\ No newline at end of file
diff --git a/DHSoftware/Views/AddCameraWindow.cs b/DHSoftware/Views/AddCameraWindow.cs
new file mode 100644
index 0000000..9da0f0a
--- /dev/null
+++ b/DHSoftware/Views/AddCameraWindow.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Xml.Linq;
+using AntdUI;
+
+namespace DHSoftware.Views
+{
+    public partial class AddCameraWindow : Window
+    {
+        public AddCameraWindow()
+        {
+            InitializeComponent();
+            btnOK.DialogResult = DialogResult.OK;
+            btnCancel.DialogResult = DialogResult.Cancel;
+            this.AcceptButton = btnOK;
+            this.CancelButton = btnCancel;
+
+            stName.Items.Clear();
+            for(int i = 1; i <= 8; i++)
+            {
+                stName.Items.Add($"Cam{i}");
+            }
+          
+        }
+        public string CubicleName { get; private set; }
+        private void btnOK_Click(object sender, EventArgs e)
+        {
+            if (ValidateInput())
+            {
+                this.DialogResult = DialogResult.OK;
+                this.Close();
+            }
+        }
+
+        private void btnCancel_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.Cancel;
+            this.Close();
+        }
+
+        private bool ValidateInput()
+        {
+            if (string.IsNullOrWhiteSpace(stName.Text))
+            {
+                MessageBox.Show("请选择关联相机", "输入错误",
+                              MessageBoxButtons.OK,
+                              MessageBoxIcon.Warning);
+                return false;
+            }
+            CubicleName = stName.Text.Trim();
+            return true;
+        }
+    }
+}
diff --git a/DHSoftware/Views/AddCameraWindow.resx b/DHSoftware/Views/AddCameraWindow.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/DHSoftware/Views/AddCameraWindow.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/DHSoftware/Views/AddCubicleWindow.Designer.cs b/DHSoftware/Views/AddCubicleWindow.Designer.cs
new file mode 100644
index 0000000..260d7d8
--- /dev/null
+++ b/DHSoftware/Views/AddCubicleWindow.Designer.cs
@@ -0,0 +1,82 @@
+namespace DHSoftware.Views
+{
+    partial class AddCubicleWindow
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            txtName = new AntdUI.Input();
+            btnOK = new AntdUI.Button();
+            btnCancel = new AntdUI.Button();
+            SuspendLayout();
+            // 
+            // txtName
+            // 
+            txtName.Location = new Point(35, 47);
+            txtName.Name = "txtName";
+            txtName.PlaceholderText = "请输入新增工位名称";
+            txtName.Size = new Size(299, 48);
+            txtName.TabIndex = 0;
+            // 
+            // btnOK
+            // 
+            btnOK.Location = new Point(170, 136);
+            btnOK.Name = "btnOK";
+            btnOK.Size = new Size(75, 40);
+            btnOK.TabIndex = 1;
+            btnOK.Text = "确定";
+            btnOK.Click += btnOK_Click;
+            // 
+            // btnCancel
+            // 
+            btnCancel.Location = new Point(259, 136);
+            btnCancel.Name = "btnCancel";
+            btnCancel.Size = new Size(75, 40);
+            btnCancel.TabIndex = 2;
+            btnCancel.Text = "取消";
+            btnCancel.Click += btnCancel_Click;
+            // 
+            // AddCubicleWindow
+            // 
+            AutoScaleDimensions = new SizeF(7F, 17F);
+            AutoScaleMode = AutoScaleMode.Font;
+            ClientSize = new Size(369, 188);
+            Controls.Add(btnCancel);
+            Controls.Add(btnOK);
+            Controls.Add(txtName);
+            Name = "AddCubicleWindow";
+            StartPosition = FormStartPosition.CenterParent;
+            Text = "AddCubicleWindow";
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private AntdUI.Input txtName;
+        private AntdUI.Button btnOK;
+        private AntdUI.Button btnCancel;
+    }
+}
\ No newline at end of file
diff --git a/DHSoftware/Views/AddCubicleWindow.cs b/DHSoftware/Views/AddCubicleWindow.cs
new file mode 100644
index 0000000..803f083
--- /dev/null
+++ b/DHSoftware/Views/AddCubicleWindow.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Xml.Linq;
+using AntdUI;
+
+namespace DHSoftware.Views
+{
+    public partial class AddCubicleWindow : Window
+    {
+        public AddCubicleWindow()
+        {
+            InitializeComponent();
+            btnOK.DialogResult = DialogResult.OK;
+            btnCancel.DialogResult = DialogResult.Cancel;
+            this.AcceptButton = btnOK;
+            this.CancelButton = btnCancel;
+        }
+        public string CubicleName { get; private set; }
+        private void btnOK_Click(object sender, EventArgs e)
+        {
+            if (ValidateInput())
+            {
+                this.DialogResult = DialogResult.OK;
+                this.Close();
+            }
+        }
+
+        private void btnCancel_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.Cancel;
+            this.Close();
+        }
+
+        private bool ValidateInput()
+        {
+            if (string.IsNullOrWhiteSpace(txtName.Text))
+            {
+                MessageBox.Show("请输入有效的名称", "输入错误",
+                              MessageBoxButtons.OK,
+                              MessageBoxIcon.Warning);
+                txtName.Focus();
+                return false;
+            }
+            CubicleName = txtName.Text.Trim();
+            return true;
+        }
+    }
+}
diff --git a/DHSoftware/Views/AddCubicleWindow.resx b/DHSoftware/Views/AddCubicleWindow.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/DHSoftware/Views/AddCubicleWindow.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/DHSoftware/Views/CorrelatedCameraEdit.Designer.cs b/DHSoftware/Views/CorrelatedCameraEdit.Designer.cs
new file mode 100644
index 0000000..e87ed35
--- /dev/null
+++ b/DHSoftware/Views/CorrelatedCameraEdit.Designer.cs
@@ -0,0 +1,149 @@
+namespace DHSoftware.Views
+{
+    partial class CorrelatedCameraEdit
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            panel1 = new AntdUI.Panel();
+            divider2 = new AntdUI.Divider();
+            stackPanel1 = new AntdUI.StackPanel();
+            button_cancel = new AntdUI.Button();
+            button_ok = new AntdUI.Button();
+            divider1 = new AntdUI.Divider();
+            label3 = new AntdUI.Label();
+            flowPanel1 = new AntdUI.FlowPanel();
+            panel1.SuspendLayout();
+            stackPanel1.SuspendLayout();
+            SuspendLayout();
+            // 
+            // panel1
+            // 
+            panel1.Controls.Add(flowPanel1);
+            panel1.Controls.Add(divider2);
+            panel1.Controls.Add(stackPanel1);
+            panel1.Controls.Add(divider1);
+            panel1.Controls.Add(label3);
+            panel1.Dock = DockStyle.Fill;
+            panel1.Location = new Point(0, 0);
+            panel1.Name = "panel1";
+            panel1.Padding = new Padding(12);
+            panel1.Shadow = 6;
+            panel1.Size = new Size(500, 358);
+            panel1.TabIndex = 0;
+            panel1.Text = "panel1";
+            // 
+            // divider2
+            // 
+            divider2.Dock = DockStyle.Top;
+            divider2.Location = new Point(18, 98);
+            divider2.Name = "divider2";
+            divider2.Size = new Size(464, 12);
+            divider2.TabIndex = 18;
+            // 
+            // stackPanel1
+            // 
+            stackPanel1.Controls.Add(button_cancel);
+            stackPanel1.Controls.Add(button_ok);
+            stackPanel1.Dock = DockStyle.Top;
+            stackPanel1.Location = new Point(18, 54);
+            stackPanel1.Name = "stackPanel1";
+            stackPanel1.RightToLeft = RightToLeft.No;
+            stackPanel1.Size = new Size(464, 44);
+            stackPanel1.TabIndex = 17;
+            stackPanel1.Text = "stackPanel1";
+            // 
+            // button_cancel
+            // 
+            button_cancel.BorderWidth = 1F;
+            button_cancel.Font = new Font("Microsoft YaHei UI", 9F);
+            button_cancel.Ghost = true;
+            button_cancel.Location = new Point(84, 3);
+            button_cancel.Name = "button_cancel";
+            button_cancel.Size = new Size(75, 38);
+            button_cancel.TabIndex = 1;
+            button_cancel.Text = "取消";
+            // 
+            // button_ok
+            // 
+            button_ok.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            button_ok.Location = new Point(3, 3);
+            button_ok.Name = "button_ok";
+            button_ok.Size = new Size(75, 38);
+            button_ok.TabIndex = 0;
+            button_ok.Text = "确定";
+            button_ok.Type = AntdUI.TTypeMini.Primary;
+            // 
+            // divider1
+            // 
+            divider1.Dock = DockStyle.Top;
+            divider1.Location = new Point(18, 42);
+            divider1.Name = "divider1";
+            divider1.Size = new Size(464, 12);
+            divider1.TabIndex = 16;
+            // 
+            // label3
+            // 
+            label3.Dock = DockStyle.Top;
+            label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label3.Location = new Point(18, 18);
+            label3.Name = "label3";
+            label3.Size = new Size(464, 24);
+            label3.TabIndex = 15;
+            label3.Text = "关联相机操作";
+            // 
+            // flowPanel1
+            // 
+            flowPanel1.Dock = DockStyle.Top;
+            flowPanel1.Location = new Point(18, 110);
+            flowPanel1.Name = "flowPanel1";
+            flowPanel1.Size = new Size(464, 227);
+            flowPanel1.TabIndex = 19;
+            flowPanel1.Text = "flowPanel1";
+            // 
+            // CorrelatedCameraEdit
+            // 
+            Controls.Add(panel1);
+            Name = "CorrelatedCameraEdit";
+            Size = new Size(500, 358);
+            Load += CorrelatedCameraEdit_Load;
+            panel1.ResumeLayout(false);
+            stackPanel1.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private AntdUI.Panel panel1;
+        private AntdUI.Label label3;
+        private AntdUI.StackPanel stackPanel1;
+        private AntdUI.Button button_cancel;
+        private AntdUI.Button button_ok;
+        private AntdUI.Divider divider1;
+        private AntdUI.Divider divider2;
+        private AntdUI.FlowPanel flowPanel1;
+    }
+}
diff --git a/DHSoftware/Views/CorrelatedCameraEdit.cs b/DHSoftware/Views/CorrelatedCameraEdit.cs
new file mode 100644
index 0000000..cc7305c
--- /dev/null
+++ b/DHSoftware/Views/CorrelatedCameraEdit.cs
@@ -0,0 +1,121 @@
+
+
+using System.ComponentModel;
+using System.Reflection;
+using AntdUI;
+using DH.Devices.Vision;
+
+namespace DHSoftware.Views
+{
+    public partial class CorrelatedCameraEdit : UserControl
+    {
+        List<KeyValuePair<string, int>> resultStates = GetFilteredEnumDescriptionsAndValuesres<ResultState>();
+
+        // 获取枚举的描述和对应的值,只筛选出 OK 和 NG
+        public static List<KeyValuePair<string, int>> GetFilteredEnumDescriptionsAndValuesres<T>() where T : Enum
+        {
+            return Enum.GetValues(typeof(T))
+                .Cast<T>()
+                /*   .Where(e => e.Equals(ResultState.OK) || e.Equals(ResultState.DetectNG))*/ // 只保留 OK 和 NG
+                .Select(e =>
+                {
+                    // 通过反射获取 DescriptionAttribute 描述,如果没有描述,则使用枚举项名称
+                    var description = e.GetType()
+                        .GetField(e.ToString())
+                        ?.GetCustomAttribute<DescriptionAttribute>()
+                        ?.Description ?? e.ToString(); // 如果没有 DescriptionAttribute,则使用枚举名称
+
+                    // 返回描述和值的键值对
+                    return new KeyValuePair<string, int>(description, Convert.ToInt32(e));
+                })
+                .ToList();
+        }
+        private AntdUI.Window window;
+        private List<RelatedCamera> Cameras;
+        public bool submit;
+        public CorrelatedCameraEdit(AntdUI.Window _window, List<RelatedCamera> cameras)
+        {
+            this.window = _window;
+            Cameras = cameras;
+            InitializeComponent();
+            //设置默认值
+            InitData();
+            // 绑定事件
+            BindEventHandler();
+        }
+
+        private void BindEventHandler()
+        {
+            button_ok.Click += Button_ok_Click;
+            button_cancel.Click += Button_cancel_Click;
+        }
+
+        private void Button_cancel_Click(object sender, EventArgs e)
+        {
+            submit = false;
+            this.Dispose();
+        }
+
+        private void Button_ok_Click(object sender, EventArgs e)
+        {
+            if (flowPanel1.Controls.Count > 0) 
+            {
+                Cameras.Clear();
+                foreach (Control control in flowPanel1.Controls)
+                {
+                    if (control is AntdUI.Checkbox checkbox)
+                    {
+                        // 操作 CheckBox
+                        bool isChecked = checkbox.Checked;
+                        if (isChecked)
+                        {
+                            string name = checkbox.Text;
+                            RelatedCamera relatedCamera = new RelatedCamera(name);
+                            Cameras.Add(relatedCamera);
+                        }
+                       
+                    }
+                }
+
+            }
+            submit = true;
+            this.Dispose();
+        }
+
+        private void InitData()
+        {
+
+
+
+            for (int i = 1; i < 15; i++)
+            {
+                string name = $"Cam{i}";
+                var control = new AntdUI.Checkbox()
+                {
+                    AutoCheck = true,
+                    Font = new System.Drawing.Font("Microsoft YaHei UI", 9F),
+                    Size = new Size(90, 42),
+                    Text = name,
+                };
+                foreach (var item in Cameras)
+                {
+                    if (item.CameraSourceId.Equals(name))
+                    {
+                        control.Checked = true;
+                        break;
+                    }
+                }
+                // 通过主窗口设置DPI控制添加控件保持缩放比例
+                window.AutoDpi(control);
+                flowPanel1.Controls.Add(control);
+                control.BringToFront();
+            }
+
+        }
+
+        private void CorrelatedCameraEdit_Load(object sender, EventArgs e)
+        {
+      
+        }
+    }
+}
diff --git a/DHSoftware/Views/CorrelatedCameraEdit.resx b/DHSoftware/Views/CorrelatedCameraEdit.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/DHSoftware/Views/CorrelatedCameraEdit.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/DHSoftware/Views/DetectConfigControl.cs b/DHSoftware/Views/DetectConfigControl.cs
index 7eff06c..54305a0 100644
--- a/DHSoftware/Views/DetectConfigControl.cs
+++ b/DHSoftware/Views/DetectConfigControl.cs
@@ -7,11 +7,15 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows.Forms;
+using DH.Devices.Vision;
 
 namespace DHSoftware.Views
 {
     public partial class DetectConfigControl : UserControl
     {
+
+        private DetectionConfig _currentConfig = new DetectionConfig();
+        private readonly string _configName;
         public DetectConfigControl()
         {
             InitializeComponent();
diff --git a/DHSoftware/Views/DetectControl.Designer.cs b/DHSoftware/Views/DetectControl.Designer.cs
new file mode 100644
index 0000000..9d4d2f3
--- /dev/null
+++ b/DHSoftware/Views/DetectControl.Designer.cs
@@ -0,0 +1,607 @@
+namespace DHSoftware.Views
+{
+    partial class DetectControl
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            AntdUI.Tabs.StyleLine styleLine1 = new AntdUI.Tabs.StyleLine();
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DetectControl));
+            tabs1 = new AntdUI.Tabs();
+            tabPage1 = new AntdUI.TabPage();
+            btnOutDelete = new AntdUI.Button();
+            btnOutAdd = new AntdUI.Button();
+            label4 = new AntdUI.Label();
+            PreOutTable = new AntdUI.Table();
+            btnPreDelete = new AntdUI.Button();
+            btnPreAdd = new AntdUI.Button();
+            preTable = new AntdUI.Table();
+            label3 = new AntdUI.Label();
+            btnPath = new AntdUI.Button();
+            switch1 = new AntdUI.Switch();
+            label2 = new AntdUI.Label();
+            iptPath = new AntdUI.Input();
+            label1 = new AntdUI.Label();
+            tabPage2 = new AntdUI.TabPage();
+            btnLableDelete = new AntdUI.Button();
+            btnLableAdd = new AntdUI.Button();
+            lableTable = new AntdUI.Table();
+            label15 = new AntdUI.Label();
+            btnPic = new AntdUI.Button();
+            switch6 = new AntdUI.Switch();
+            label13 = new AntdUI.Label();
+            switch7 = new AntdUI.Switch();
+            label14 = new AntdUI.Label();
+            switch4 = new AntdUI.Switch();
+            label6 = new AntdUI.Label();
+            switch5 = new AntdUI.Switch();
+            label12 = new AntdUI.Label();
+            input1 = new AntdUI.Input();
+            label5 = new AntdUI.Label();
+            flowPanel1 = new AntdUI.FlowPanel();
+            label11 = new AntdUI.Label();
+            switch3 = new AntdUI.Switch();
+            label10 = new AntdUI.Label();
+            stDetectType = new AntdUI.Select();
+            label9 = new AntdUI.Label();
+            btnCorrelatedCamera = new AntdUI.Button();
+            btnPath2 = new AntdUI.Button();
+            switch2 = new AntdUI.Switch();
+            label7 = new AntdUI.Label();
+            iptPath2 = new AntdUI.Input();
+            label8 = new AntdUI.Label();
+            tabPage3 = new AntdUI.TabPage();
+            tabs1.SuspendLayout();
+            tabPage1.SuspendLayout();
+            tabPage2.SuspendLayout();
+            SuspendLayout();
+            // 
+            // tabs1
+            // 
+            tabs1.Centered = true;
+            tabs1.Dock = DockStyle.Fill;
+            tabs1.Font = new Font("Microsoft YaHei UI", 10.5F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            tabs1.Location = new Point(0, 0);
+            tabs1.Name = "tabs1";
+            tabs1.Pages.Add(tabPage1);
+            tabs1.Pages.Add(tabPage2);
+            tabs1.Pages.Add(tabPage3);
+            tabs1.SelectedIndex = 1;
+            tabs1.Size = new Size(915, 609);
+            tabs1.Style = styleLine1;
+            tabs1.TabIndex = 2;
+            tabs1.Text = "tabs1";
+            // 
+            // tabPage1
+            // 
+            tabPage1.Controls.Add(btnOutDelete);
+            tabPage1.Controls.Add(btnOutAdd);
+            tabPage1.Controls.Add(label4);
+            tabPage1.Controls.Add(PreOutTable);
+            tabPage1.Controls.Add(btnPreDelete);
+            tabPage1.Controls.Add(btnPreAdd);
+            tabPage1.Controls.Add(preTable);
+            tabPage1.Controls.Add(label3);
+            tabPage1.Controls.Add(btnPath);
+            tabPage1.Controls.Add(switch1);
+            tabPage1.Controls.Add(label2);
+            tabPage1.Controls.Add(iptPath);
+            tabPage1.Controls.Add(label1);
+            tabPage1.Location = new Point(-822, -575);
+            tabPage1.Name = "tabPage1";
+            tabPage1.Size = new Size(822, 575);
+            tabPage1.TabIndex = 0;
+            tabPage1.Text = "预处理";
+            // 
+            // btnOutDelete
+            // 
+            btnOutDelete.BorderWidth = 2F;
+            btnOutDelete.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnOutDelete.Ghost = true;
+            btnOutDelete.IconRatio = 0.8F;
+            btnOutDelete.IconSvg = resources.GetString("btnOutDelete.IconSvg");
+            btnOutDelete.Location = new Point(620, 472);
+            btnOutDelete.Name = "btnOutDelete";
+            btnOutDelete.Size = new Size(80, 38);
+            btnOutDelete.TabIndex = 14;
+            btnOutDelete.Text = "删除";
+            // 
+            // btnOutAdd
+            // 
+            btnOutAdd.BorderWidth = 2F;
+            btnOutAdd.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnOutAdd.Ghost = true;
+            btnOutAdd.IconRatio = 0.8F;
+            btnOutAdd.IconSvg = resources.GetString("btnOutAdd.IconSvg");
+            btnOutAdd.Location = new Point(620, 411);
+            btnOutAdd.Name = "btnOutAdd";
+            btnOutAdd.Size = new Size(80, 38);
+            btnOutAdd.TabIndex = 13;
+            btnOutAdd.Text = "新增";
+            // 
+            // label4
+            // 
+            label4.Location = new Point(110, 440);
+            label4.Name = "label4";
+            label4.Size = new Size(75, 23);
+            label4.TabIndex = 12;
+            label4.Text = "输出参数";
+            // 
+            // PreOutTable
+            // 
+            PreOutTable.Location = new Point(191, 355);
+            PreOutTable.Name = "PreOutTable";
+            PreOutTable.Size = new Size(423, 181);
+            PreOutTable.TabIndex = 11;
+            PreOutTable.Text = "table1";
+            // 
+            // btnPreDelete
+            // 
+            btnPreDelete.BorderWidth = 2F;
+            btnPreDelete.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnPreDelete.Ghost = true;
+            btnPreDelete.IconRatio = 0.8F;
+            btnPreDelete.IconSvg = resources.GetString("btnPreDelete.IconSvg");
+            btnPreDelete.Location = new Point(620, 255);
+            btnPreDelete.Name = "btnPreDelete";
+            btnPreDelete.Size = new Size(80, 38);
+            btnPreDelete.TabIndex = 10;
+            btnPreDelete.Text = "删除";
+            // 
+            // btnPreAdd
+            // 
+            btnPreAdd.BorderWidth = 2F;
+            btnPreAdd.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnPreAdd.Ghost = true;
+            btnPreAdd.IconRatio = 0.8F;
+            btnPreAdd.IconSvg = resources.GetString("btnPreAdd.IconSvg");
+            btnPreAdd.Location = new Point(620, 191);
+            btnPreAdd.Name = "btnPreAdd";
+            btnPreAdd.Size = new Size(80, 38);
+            btnPreAdd.TabIndex = 9;
+            btnPreAdd.Text = "新增";
+            // 
+            // preTable
+            // 
+            preTable.Location = new Point(191, 148);
+            preTable.Name = "preTable";
+            preTable.Size = new Size(423, 181);
+            preTable.TabIndex = 8;
+            preTable.Text = "table1";
+            // 
+            // label3
+            // 
+            label3.Location = new Point(110, 206);
+            label3.Name = "label3";
+            label3.Size = new Size(75, 23);
+            label3.TabIndex = 1;
+            label3.Text = "输入参数";
+            // 
+            // btnPath
+            // 
+            btnPath.BorderWidth = 2F;
+            btnPath.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnPath.Ghost = true;
+            btnPath.IconRatio = 0.8F;
+            btnPath.IconSvg = resources.GetString("btnPath.IconSvg");
+            btnPath.Location = new Point(620, 79);
+            btnPath.Name = "btnPath";
+            btnPath.Size = new Size(80, 38);
+            btnPath.TabIndex = 7;
+            btnPath.Text = "打开";
+            // 
+            // switch1
+            // 
+            switch1.CheckedText = "启用";
+            switch1.Location = new Point(207, 33);
+            switch1.Name = "switch1";
+            switch1.Size = new Size(82, 33);
+            switch1.TabIndex = 4;
+            switch1.UnCheckedText = "关闭";
+            // 
+            // label2
+            // 
+            label2.Location = new Point(110, 40);
+            label2.Name = "label2";
+            label2.Size = new Size(75, 23);
+            label2.TabIndex = 3;
+            label2.Text = "状      态";
+            // 
+            // iptPath
+            // 
+            iptPath.Location = new Point(191, 79);
+            iptPath.Name = "iptPath";
+            iptPath.PlaceholderText = "请点击打开按钮选择模型路径";
+            iptPath.ReadOnly = true;
+            iptPath.Size = new Size(423, 42);
+            iptPath.TabIndex = 1;
+            // 
+            // label1
+            // 
+            label1.Location = new Point(110, 89);
+            label1.Name = "label1";
+            label1.Size = new Size(75, 23);
+            label1.TabIndex = 0;
+            label1.Text = "模型路径";
+            // 
+            // tabPage2
+            // 
+            tabPage2.Controls.Add(btnLableDelete);
+            tabPage2.Controls.Add(btnLableAdd);
+            tabPage2.Controls.Add(lableTable);
+            tabPage2.Controls.Add(label15);
+            tabPage2.Controls.Add(btnPic);
+            tabPage2.Controls.Add(switch6);
+            tabPage2.Controls.Add(label13);
+            tabPage2.Controls.Add(switch7);
+            tabPage2.Controls.Add(label14);
+            tabPage2.Controls.Add(switch4);
+            tabPage2.Controls.Add(label6);
+            tabPage2.Controls.Add(switch5);
+            tabPage2.Controls.Add(label12);
+            tabPage2.Controls.Add(input1);
+            tabPage2.Controls.Add(label5);
+            tabPage2.Controls.Add(flowPanel1);
+            tabPage2.Controls.Add(label11);
+            tabPage2.Controls.Add(switch3);
+            tabPage2.Controls.Add(label10);
+            tabPage2.Controls.Add(stDetectType);
+            tabPage2.Controls.Add(label9);
+            tabPage2.Controls.Add(btnCorrelatedCamera);
+            tabPage2.Controls.Add(btnPath2);
+            tabPage2.Controls.Add(switch2);
+            tabPage2.Controls.Add(label7);
+            tabPage2.Controls.Add(iptPath2);
+            tabPage2.Controls.Add(label8);
+            tabPage2.Location = new Point(3, 31);
+            tabPage2.Name = "tabPage2";
+            tabPage2.Size = new Size(909, 575);
+            tabPage2.TabIndex = 1;
+            tabPage2.Text = "模型检测";
+            // 
+            // btnLableDelete
+            // 
+            btnLableDelete.BorderWidth = 2F;
+            btnLableDelete.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnLableDelete.Ghost = true;
+            btnLableDelete.IconRatio = 0.8F;
+            btnLableDelete.IconSvg = resources.GetString("btnLableDelete.IconSvg");
+            btnLableDelete.Location = new Point(772, 300);
+            btnLableDelete.Name = "btnLableDelete";
+            btnLableDelete.Size = new Size(90, 38);
+            btnLableDelete.TabIndex = 48;
+            btnLableDelete.Text = "删除";
+            // 
+            // btnLableAdd
+            // 
+            btnLableAdd.BorderWidth = 2F;
+            btnLableAdd.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnLableAdd.Ghost = true;
+            btnLableAdd.IconRatio = 0.8F;
+            btnLableAdd.IconSvg = resources.GetString("btnLableAdd.IconSvg");
+            btnLableAdd.Location = new Point(772, 256);
+            btnLableAdd.Name = "btnLableAdd";
+            btnLableAdd.Size = new Size(90, 38);
+            btnLableAdd.TabIndex = 47;
+            btnLableAdd.Text = "新增";
+            // 
+            // lableTable
+            // 
+            lableTable.BackColor = SystemColors.ControlLight;
+            lableTable.Location = new Point(110, 252);
+            lableTable.Name = "lableTable";
+            lableTable.Size = new Size(656, 288);
+            lableTable.TabIndex = 46;
+            lableTable.Text = "table1";
+            // 
+            // label15
+            // 
+            label15.Location = new Point(29, 252);
+            label15.Name = "label15";
+            label15.Size = new Size(75, 23);
+            label15.TabIndex = 45;
+            label15.Text = "标签集合";
+            // 
+            // btnPic
+            // 
+            btnPic.BorderWidth = 2F;
+            btnPic.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnPic.Ghost = true;
+            btnPic.IconRatio = 0.8F;
+            btnPic.IconSvg = resources.GetString("btnPic.IconSvg");
+            btnPic.Location = new Point(772, 193);
+            btnPic.Name = "btnPic";
+            btnPic.Size = new Size(90, 38);
+            btnPic.TabIndex = 44;
+            btnPic.Text = "查看图片";
+            // 
+            // switch6
+            // 
+            switch6.CheckedText = "启用";
+            switch6.Location = new Point(607, 194);
+            switch6.Name = "switch6";
+            switch6.Size = new Size(82, 33);
+            switch6.TabIndex = 43;
+            switch6.UnCheckedText = "关闭";
+            // 
+            // label13
+            // 
+            label13.Location = new Point(536, 201);
+            label13.Name = "label13";
+            label13.Size = new Size(75, 23);
+            label13.TabIndex = 42;
+            label13.Text = "NG检测图";
+            // 
+            // switch7
+            // 
+            switch7.CheckedText = "启用";
+            switch7.Location = new Point(438, 194);
+            switch7.Name = "switch7";
+            switch7.Size = new Size(82, 33);
+            switch7.TabIndex = 41;
+            switch7.UnCheckedText = "关闭";
+            // 
+            // label14
+            // 
+            label14.Location = new Point(369, 201);
+            label14.Name = "label14";
+            label14.Size = new Size(75, 23);
+            label14.TabIndex = 40;
+            label14.Text = "OK检测图";
+            // 
+            // switch4
+            // 
+            switch4.CheckedText = "启用";
+            switch4.Location = new Point(270, 194);
+            switch4.Name = "switch4";
+            switch4.Size = new Size(82, 33);
+            switch4.TabIndex = 39;
+            switch4.UnCheckedText = "关闭";
+            // 
+            // label6
+            // 
+            label6.Location = new Point(198, 201);
+            label6.Name = "label6";
+            label6.Size = new Size(75, 23);
+            label6.TabIndex = 38;
+            label6.Text = "NG原图";
+            // 
+            // switch5
+            // 
+            switch5.CheckedText = "启用";
+            switch5.Location = new Point(110, 194);
+            switch5.Name = "switch5";
+            switch5.Size = new Size(82, 33);
+            switch5.TabIndex = 37;
+            switch5.UnCheckedText = "关闭";
+            // 
+            // label12
+            // 
+            label12.Location = new Point(29, 201);
+            label12.Name = "label12";
+            label12.Size = new Size(75, 23);
+            label12.TabIndex = 36;
+            label12.Text = "OK原图";
+            // 
+            // input1
+            // 
+            input1.Location = new Point(649, 24);
+            input1.Name = "input1";
+            input1.PlaceholderText = "";
+            input1.ReadOnly = true;
+            input1.Size = new Size(117, 42);
+            input1.TabIndex = 35;
+            // 
+            // label5
+            // 
+            label5.Location = new Point(600, 33);
+            label5.Name = "label5";
+            label5.Size = new Size(62, 23);
+            label5.TabIndex = 34;
+            label5.Text = "置信度";
+            // 
+            // flowPanel1
+            // 
+            flowPanel1.AutoScroll = true;
+            flowPanel1.BackColor = SystemColors.ControlLight;
+            flowPanel1.Location = new Point(110, 136);
+            flowPanel1.Name = "flowPanel1";
+            flowPanel1.Size = new Size(656, 49);
+            flowPanel1.TabIndex = 33;
+            flowPanel1.Text = "flowPanel1";
+            // 
+            // label11
+            // 
+            label11.Location = new Point(29, 151);
+            label11.Name = "label11";
+            label11.Size = new Size(75, 23);
+            label11.TabIndex = 32;
+            label11.Text = "关联相机";
+            // 
+            // switch3
+            // 
+            switch3.CheckedText = "启用";
+            switch3.Location = new Point(270, 26);
+            switch3.Name = "switch3";
+            switch3.Size = new Size(82, 33);
+            switch3.TabIndex = 31;
+            switch3.UnCheckedText = "关闭";
+            // 
+            // label10
+            // 
+            label10.Location = new Point(198, 33);
+            label10.Name = "label10";
+            label10.Size = new Size(75, 23);
+            label10.TabIndex = 30;
+            label10.Text = "检测工位";
+            // 
+            // stDetectType
+            // 
+            stDetectType.List = true;
+            stDetectType.Location = new Point(426, 26);
+            stDetectType.MaxCount = 5;
+            stDetectType.Name = "stDetectType";
+            stDetectType.PlaceholderText = "请选择检测类型";
+            stDetectType.Size = new Size(157, 40);
+            stDetectType.TabIndex = 29;
+            // 
+            // label9
+            // 
+            label9.Location = new Point(358, 33);
+            label9.Name = "label9";
+            label9.Size = new Size(75, 23);
+            label9.TabIndex = 28;
+            label9.Text = "检测类型";
+            // 
+            // btnCorrelatedCamera
+            // 
+            btnCorrelatedCamera.BorderWidth = 2F;
+            btnCorrelatedCamera.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnCorrelatedCamera.Ghost = true;
+            btnCorrelatedCamera.IconRatio = 0.8F;
+            btnCorrelatedCamera.IconSvg = resources.GetString("btnCorrelatedCamera.IconSvg");
+            btnCorrelatedCamera.Location = new Point(772, 140);
+            btnCorrelatedCamera.Name = "btnCorrelatedCamera";
+            btnCorrelatedCamera.Size = new Size(90, 38);
+            btnCorrelatedCamera.TabIndex = 22;
+            btnCorrelatedCamera.Text = "关联";
+            // 
+            // btnPath2
+            // 
+            btnPath2.BorderWidth = 2F;
+            btnPath2.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            btnPath2.Ghost = true;
+            btnPath2.IconRatio = 0.8F;
+            btnPath2.IconSvg = resources.GetString("btnPath2.IconSvg");
+            btnPath2.Location = new Point(772, 79);
+            btnPath2.Name = "btnPath2";
+            btnPath2.Size = new Size(90, 38);
+            btnPath2.TabIndex = 20;
+            btnPath2.Text = "打开";
+            // 
+            // switch2
+            // 
+            switch2.CheckedText = "启用";
+            switch2.Location = new Point(110, 26);
+            switch2.Name = "switch2";
+            switch2.Size = new Size(82, 33);
+            switch2.TabIndex = 19;
+            switch2.UnCheckedText = "关闭";
+            // 
+            // label7
+            // 
+            label7.Location = new Point(29, 33);
+            label7.Name = "label7";
+            label7.Size = new Size(75, 23);
+            label7.TabIndex = 18;
+            label7.Text = "状      态";
+            // 
+            // iptPath2
+            // 
+            iptPath2.Location = new Point(110, 75);
+            iptPath2.Name = "iptPath2";
+            iptPath2.PlaceholderText = "请点击打开按钮选择模型路径";
+            iptPath2.ReadOnly = true;
+            iptPath2.Size = new Size(656, 42);
+            iptPath2.TabIndex = 17;
+            // 
+            // label8
+            // 
+            label8.Location = new Point(29, 90);
+            label8.Name = "label8";
+            label8.Size = new Size(75, 23);
+            label8.TabIndex = 15;
+            label8.Text = "模型路径";
+            // 
+            // tabPage3
+            // 
+            tabPage3.Location = new Point(0, 0);
+            tabPage3.Name = "tabPage3";
+            tabPage3.Size = new Size(0, 0);
+            tabPage3.TabIndex = 2;
+            tabPage3.Text = "尺寸测量";
+            // 
+            // DetectControl
+            // 
+            AutoScaleDimensions = new SizeF(7F, 17F);
+            AutoScaleMode = AutoScaleMode.Font;
+            Controls.Add(tabs1);
+            Name = "DetectControl";
+            Size = new Size(915, 609);
+            tabs1.ResumeLayout(false);
+            tabPage1.ResumeLayout(false);
+            tabPage2.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private AntdUI.Tabs tabs1;
+        private AntdUI.TabPage tabPage1;
+        private AntdUI.TabPage tabPage2;
+        private AntdUI.TabPage tabPage3;
+        private AntdUI.Label label1;
+        private AntdUI.Input iptPath;
+        private AntdUI.Label label2;
+        private AntdUI.Switch switch1;
+        private AntdUI.Button btnPath;
+        private AntdUI.Label label3;
+        private AntdUI.Button btnPreDelete;
+        private AntdUI.Button btnPreAdd;
+        private AntdUI.Table preTable;
+        private AntdUI.Button btnOutDelete;
+        private AntdUI.Button btnOutAdd;
+        private AntdUI.Label label4;
+        private AntdUI.Table PreOutTable;
+        private AntdUI.Button btnCorrelatedCamera;
+        private AntdUI.Button btnPath2;
+        private AntdUI.Switch switch2;
+        private AntdUI.Label label7;
+        private AntdUI.Input iptPath2;
+        private AntdUI.Label label8;
+        private AntdUI.Select stDetectType;
+        private AntdUI.Label label9;
+        private AntdUI.Switch switch3;
+        private AntdUI.Label label10;
+        private AntdUI.Label label11;
+        private AntdUI.FlowPanel flowPanel1;
+        private AntdUI.Label label5;
+        private AntdUI.Input input1;
+        private AntdUI.Switch switch4;
+        private AntdUI.Label label6;
+        private AntdUI.Switch switch5;
+        private AntdUI.Label label12;
+        private AntdUI.Switch switch6;
+        private AntdUI.Label label13;
+        private AntdUI.Switch switch7;
+        private AntdUI.Label label14;
+        private AntdUI.Button btnPic;
+        private AntdUI.Label label15;
+        private AntdUI.Table lableTable;
+        private AntdUI.Button btnLableAdd;
+        private AntdUI.Button btnLableDelete;
+    }
+}
diff --git a/DHSoftware/Views/DetectControl.cs b/DHSoftware/Views/DetectControl.cs
new file mode 100644
index 0000000..4348fe7
--- /dev/null
+++ b/DHSoftware/Views/DetectControl.cs
@@ -0,0 +1,480 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Xml.Linq;
+using AntdUI;
+using DH.Devices.Vision;
+
+namespace DHSoftware.Views
+{
+    public partial class DetectControl : UserControl
+    {
+        Window window;
+        public DetectControl(Window _window)
+        {
+            window= _window;
+            InitializeComponent();
+            //初始化表格列头
+            InitTableColumns();
+            InitData();
+            BindEventHandler();
+        }
+
+        private void BindEventHandler()
+        {
+            //预处理
+            btnPath.Click += btnPath_Click;
+            btnPreAdd.Click += BtnPreAdd_Click; ;
+            btnPreDelete.Click += BtnPreDelete_Click; ;
+            preTable.CellClick += PreTable_CellClick; ;
+            preTable.CellButtonClick += PreTable_CellButtonClick;
+            btnOutAdd.Click += BtnOutAdd_Click; ;
+            btnOutDelete.Click += BtnOutDelete_Click; ;
+            PreOutTable.CellButtonClick += PreOutTable_CellButtonClick; ;
+
+            //中处理
+            btnPath2.Click += BtnPath2_Click;
+            btnCorrelatedCamera.Click += BtnCorrelatedCamera_Click;
+            btnPic.Click += BtnPic_Click;
+            btnLableAdd.Click += BtnLableAdd_Click;
+            btnLableDelete.Click += BtnLableDelete_Click;
+            lableTable.CellButtonClick += LableTable_CellButtonClick;
+
+        }
+
+        private void LableTable_CellButtonClick(object sender, TableButtonEventArgs e)
+        {
+            var buttontext = e.Btn.Text;
+
+            if (e.Record is DetectionLable DetectionLable)
+            {
+                curDetectionLable = DetectionLable;
+                switch (buttontext)
+                {
+                    //暂不支持进入整行编辑,只支持指定单元格编辑,推荐使用弹窗或抽屉编辑整行数据
+                    case "编辑":
+                        var form = new DetectionLableEdit(window, curDetectionLable) { Size = new Size(500, 300) };
+                        AntdUI.Drawer.open(new AntdUI.Drawer.Config(window, form)
+                        {
+                            OnLoad = () =>
+                            {
+                                AntdUI.Message.info(window, "进入编辑", autoClose: 1);
+                            },
+                            OnClose = () =>
+                            {
+                                AntdUI.Message.info(window, "结束编辑", autoClose: 1);
+                            }
+                        });
+                        break;
+                    case "删除":
+                        var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
+                        if (result == DialogResult.OK)
+                            DetectionLableList.Remove(DetectionLable);
+                        break;
+
+                }
+            }
+        }
+
+        private void BtnLableDelete_Click(object? sender, EventArgs e)
+        {
+            if (DetectionLableList.Count == 0 || !DetectionLableList.Any(x => x.Selected))
+            {
+                AntdUI.Message.warn(window, "请选择要删除的行!", autoClose: 3);
+                return;
+            }
+
+            var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
+            if (result == DialogResult.OK)
+            {
+                // 使用反转for循环删除主列表中选中的项
+                for (int i = DetectionLableList.Count - 1; i >= 0; i--)
+                {
+                    // 删除选中的主列表项
+                    if (DetectionLableList[i].Selected)
+                    {
+                        DetectionLableList.RemoveAt(i);
+                    }
+                }
+                // 提示删除完成
+                AntdUI.Message.success(window, "删除成功!", autoClose: 3);
+            }
+        }
+
+        private void BtnLableAdd_Click(object? sender, EventArgs e)
+        {
+            DetectionLable  detectionLable = new DetectionLable()
+            {
+                CellLinks = new CellLink[] {
+                    new CellButton(Guid.NewGuid().ToString(),"编辑",TTypeMini.Primary),
+                    new CellButton(Guid.NewGuid().ToString(),"删除",TTypeMini.Error),
+                   }
+            };
+            var form = new DetectionLableEdit(window, detectionLable) { Size = new Size(450, 500) };
+            AntdUI.Modal.open(new AntdUI.Modal.Config(window, "", form, TType.None)
+            {
+                BtnHeight = 0,
+            });
+            if (form.submit)
+            {
+                DetectionLableList.Add(detectionLable);
+            }
+        }
+
+        private void BtnPic_Click(object? sender, EventArgs e)
+        {
+           
+        }
+
+        List<RelatedCamera> relatedCameras = new List<RelatedCamera>();
+        private void BtnCorrelatedCamera_Click(object? sender, EventArgs e)
+        {
+           
+
+
+            var form = new CorrelatedCameraEdit(window, relatedCameras) { Size = new Size(500, 400) };
+            AntdUI.Modal.open(new AntdUI.Modal.Config(window, "", form, TType.None)
+            {
+                BtnHeight = 0,
+            });
+            if (form.submit)
+            {
+                flowPanel1.Controls.Clear();
+                if (relatedCameras.Count > 0)
+                {
+                    foreach (var item in relatedCameras)
+                    {
+                        var control = new AntdUI.Tag()
+                        {
+                            Font = new System.Drawing.Font("Microsoft YaHei UI", 9F),
+                            Size = new Size(90, 42),
+                            Text = item.CameraSourceId,
+                            CloseIcon = true
+                        };
+                        control.CloseChanged += (sender, e) =>
+                        {
+                            var tag = sender as Tag;
+                            foreach (var item in relatedCameras)
+                            {
+                                if (item.CameraSourceId.Equals(tag.Text))
+                                {
+                                    relatedCameras.Remove(item);
+                                    break;
+                                }
+                            }
+                            return true;
+
+                        };
+                        // 通过主窗口设置DPI控制添加控件保持缩放比例
+                        window.AutoDpi(control);
+                        flowPanel1.Controls.Add(control);
+                        control.BringToFront();
+                    }
+                }
+            }              
+     }
+
+        private bool Control_CloseChanged(object sender, EventArgs e)
+        {
+            throw new NotImplementedException();
+        }
+
+        private void BtnPath2_Click(object? sender, EventArgs e)
+        {
+            using (OpenFileDialog openFileDialog = new OpenFileDialog())
+            {
+                // 设置对话框标题
+                openFileDialog.Title = "选择中处理文件";
+                // 限制文件后缀为 .onnx、trt
+                openFileDialog.Filter = "中处理文件  (*.onnx, *.trt)|*.onnx;*.trt";
+                // 禁止多选
+                openFileDialog.Multiselect = false;
+
+                // 显示对话框并等待用户操作
+                if (openFileDialog.ShowDialog() == DialogResult.OK)
+                {
+                    string filePath = openFileDialog.FileName;
+
+                    iptPath2.Text = filePath;
+
+                }
+            }
+        }
+
+        private void PreOutTable_CellButtonClick(object sender, TableButtonEventArgs e)
+        {
+            var buttontext = e.Btn.Text;
+
+            if (e.Record is PreTreatParam PreTreat)
+            {
+                curPreOutTreat = PreTreat;
+                switch (buttontext)
+                {
+                    //暂不支持进入整行编辑,只支持指定单元格编辑,推荐使用弹窗或抽屉编辑整行数据
+                    case "编辑":
+                        var form = new PreTreatEdit(window, curPreOutTreat) { Size = new Size(500, 300) };
+                        AntdUI.Drawer.open(new AntdUI.Drawer.Config(window, form)
+                        {
+                            OnLoad = () =>
+                            {
+                                AntdUI.Message.info(window, "进入编辑", autoClose: 1);
+                            },
+                            OnClose = () =>
+                            {
+                                AntdUI.Message.info(window, "结束编辑", autoClose: 1);
+                            }
+                        });
+                        break;
+                    case "删除":
+                        var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
+                        if (result == DialogResult.OK)
+                            PreOutTreatList.Remove(PreTreat);
+                        break;
+
+                }
+            }
+        }
+
+        private void BtnOutDelete_Click(object? sender, EventArgs e)
+        {
+            if (PreOutTreatList.Count == 0 || !PreOutTreatList.Any(x => x.Selected))
+            {
+                AntdUI.Message.warn(window, "请选择要删除的行!", autoClose: 3);
+                return;
+            }
+
+            var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
+            if (result == DialogResult.OK)
+            {
+                // 使用反转for循环删除主列表中选中的项
+                for (int i = PreOutTreatList.Count - 1; i >= 0; i--)
+                {
+                    // 删除选中的主列表项
+                    if (PreOutTreatList[i].Selected)
+                    {
+                        PreOutTreatList.RemoveAt(i);
+                    }
+                }
+                // 提示删除完成
+                AntdUI.Message.success(window, "删除成功!", autoClose: 3);
+            }
+        }
+
+        private void BtnOutAdd_Click(object? sender, EventArgs e)
+        {
+            PreTreatParam preParam = new PreTreatParam()
+            {
+                CellLinks = new CellLink[] {
+                    new CellButton(Guid.NewGuid().ToString(),"编辑",TTypeMini.Primary),
+                    new CellButton(Guid.NewGuid().ToString(),"删除",TTypeMini.Error),
+                   }
+            };
+            var form = new PreTreatEdit(window, preParam) { Size = new Size(400, 300) };
+            AntdUI.Modal.open(new AntdUI.Modal.Config(window, "", form, TType.None)
+            {
+                BtnHeight = 0,
+            });
+            if (form.submit)
+            {
+                PreOutTreatList.Add(preParam);
+            }
+        }
+
+        private void PreTable_CellButtonClick(object sender, TableButtonEventArgs e)
+        {
+            var buttontext = e.Btn.Text;
+
+            if (e.Record is PreTreatParam PreTreat)
+            {
+                curPreTreat = PreTreat;
+                switch (buttontext)
+                {
+                    //暂不支持进入整行编辑,只支持指定单元格编辑,推荐使用弹窗或抽屉编辑整行数据
+                    case "编辑":
+                        var form = new PreTreatEdit(window, curPreTreat) { Size = new Size(500, 300) };
+                        AntdUI.Drawer.open(new AntdUI.Drawer.Config(window, form)
+                        {
+                            OnLoad = () =>
+                            {
+                                AntdUI.Message.info(window, "进入编辑", autoClose: 1);
+                            },
+                            OnClose = () =>
+                            {
+                                AntdUI.Message.info(window, "结束编辑", autoClose: 1);
+                            }
+                        });
+                        break;
+                    case "删除":
+                        var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
+                        if (result == DialogResult.OK)
+                            PreTreatList.Remove(PreTreat);
+                        break;
+                
+                }
+            }
+        }
+
+        private void PreTable_CellClick(object sender, TableClickEventArgs e)
+        {
+        }
+               
+               
+
+        private void BtnPreDelete_Click(object? sender, EventArgs e)
+        {
+            if (PreTreatList.Count == 0 || !PreTreatList.Any(x => x.Selected))
+            {
+                    AntdUI.Message.warn(window, "请选择要删除的行!", autoClose: 3);
+                    return;
+            }
+
+            var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
+            if (result == DialogResult.OK)
+            {
+                // 使用反转for循环删除主列表中选中的项
+                for (int i = PreTreatList.Count - 1; i >= 0; i--)
+                {
+                    // 删除选中的主列表项
+                    if (PreTreatList[i].Selected)
+                    {
+                        PreTreatList.RemoveAt(i);
+                    }
+                }
+                // 提示删除完成
+                AntdUI.Message.success(window, "删除成功!", autoClose: 3);
+            }
+        }
+
+        private void BtnPreAdd_Click(object? sender, EventArgs e)
+        {
+            PreTreatParam preParam = new PreTreatParam()
+            {
+                CellLinks = new CellLink[] {
+                    new CellButton(Guid.NewGuid().ToString(),"编辑",TTypeMini.Primary),
+                    new CellButton(Guid.NewGuid().ToString(),"删除",TTypeMini.Error),
+                   }
+            };
+            var form = new PreTreatEdit(window, preParam) { Size = new Size(400, 300) };
+            AntdUI.Modal.open(new AntdUI.Modal.Config(window, "", form, TType.None)
+            {
+                BtnHeight = 0,
+            });
+            if (form.submit)
+            {
+                PreTreatList.Add(preParam);
+            }
+        }
+
+        AntList<PreTreatParam> PreTreatList;
+        AntList<PreTreatParam> PreOutTreatList;
+        AntList<DetectionLable> DetectionLableList;
+        PreTreatParam curPreTreat;
+        PreTreatParam curPreOutTreat;
+        DetectionLable curDetectionLable;
+        private void InitData()
+        {
+            PreTreatList = new AntList<PreTreatParam>();
+
+            preTable.Binding(PreTreatList);
+
+            PreOutTreatList = new AntList<PreTreatParam>();
+
+            PreOutTable.Binding(PreOutTreatList);
+
+           
+            foreach (var item in MLModelTypes)
+            {
+                stDetectType.Items.Add(item.Key);
+            }
+
+
+            DetectionLableList =new AntList<DetectionLable>();
+
+            lableTable.Binding(DetectionLableList);
+
+        }
+
+        private void InitTableColumns()
+        {
+            preTable.Columns = new ColumnCollection() {
+                new ColumnCheck("Selected"){Fixed = true},
+                new Column("Name", "名称", ColumnAlign.Center),
+                new Column("Value", "值",ColumnAlign.Center),
+                new Column("CellLinks", "操作", ColumnAlign.Center)
+            };
+
+            PreOutTable.Columns = new ColumnCollection() {
+                new ColumnCheck("Selected"){Fixed = true},
+                new Column("Name", "名称", ColumnAlign.Center),
+                new Column("Value", "值",ColumnAlign.Center),
+                new Column("CellLinks", "操作", ColumnAlign.Center)
+            };
+
+
+            lableTable.Columns = new ColumnCollection() {
+                new ColumnCheck("Selected"){Fixed = true},
+                new Column("LabelName", "名称", ColumnAlign.Center),
+                new Column("MinSource", "最小得分",ColumnAlign.Center),
+                new Column("MaxArea", "最大得分", ColumnAlign.Center),
+                new Column("MinSource", "最小面积",ColumnAlign.Center),
+                new Column("MaxArea", "最大面积", ColumnAlign.Center),
+                new Column("ResultState", "结果", ColumnAlign.Center),
+                new Column("CellLinks", "操作", ColumnAlign.Center)
+            };
+        }
+
+        private void btnPath_Click(object? sender, EventArgs e)
+        {
+            using (OpenFileDialog openFileDialog = new OpenFileDialog())
+            {
+                // 设置对话框标题
+                openFileDialog.Title = "选择预处理文件";
+                // 限制文件后缀为 .hdvp
+                openFileDialog.Filter = "中处理 (*.hdvp)|*.hdvp";
+                // 禁止多选
+                openFileDialog.Multiselect = false;
+
+                // 显示对话框并等待用户操作
+                if (openFileDialog.ShowDialog() == DialogResult.OK)
+                {
+                    string filePath = openFileDialog.FileName;
+                   
+                    iptPath.Text = filePath;
+  
+                }
+            }
+        }
+
+
+ 
+
+
+        List<KeyValuePair<string, int>> MLModelTypes = GetFilteredEnumDescriptionsAndValues<MLModelType>();
+
+        public static List<KeyValuePair<string, int>> GetFilteredEnumDescriptionsAndValues<T>() where T : Enum
+        {
+            return Enum.GetValues(typeof(T))
+                .Cast<T>()
+                .Select(e =>
+                {
+                    // 获取枚举的 Description 属性,如果没有,则使用枚举的名称
+                    var description = e.GetType()
+                        .GetField(e.ToString())
+                        ?.GetCustomAttribute<DescriptionAttribute>()
+                        ?.Description ?? e.ToString();
+
+                    // 返回枚举的描述和对应的整数值
+                    return new KeyValuePair<string, int>(description, Convert.ToInt32(e));
+                })
+                .ToList();
+        }
+    }
+
+}
diff --git a/DHSoftware/Views/DetectControl.resx b/DHSoftware/Views/DetectControl.resx
new file mode 100644
index 0000000..8dd9521
--- /dev/null
+++ b/DHSoftware/Views/DetectControl.resx
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="btnOutDelete.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnOutAdd.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnPreDelete.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnPreAdd.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnPath.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnLableDelete.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnLableAdd.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnPic.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnCorrelatedCamera.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+  <data name="btnPath2.IconSvg" xml:space="preserve">
+    <value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/DHSoftware/Views/DetectionLableEdit.Designer.cs b/DHSoftware/Views/DetectionLableEdit.Designer.cs
new file mode 100644
index 0000000..4ec865c
--- /dev/null
+++ b/DHSoftware/Views/DetectionLableEdit.Designer.cs
@@ -0,0 +1,290 @@
+namespace DHSoftware.Views
+{
+    partial class DetectionLableEdit
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            panel1 = new AntdUI.Panel();
+            sltResultState = new AntdUI.Select();
+            label7 = new AntdUI.Label();
+            iptMaxArea = new AntdUI.Input();
+            label6 = new AntdUI.Label();
+            iptMinArea = new AntdUI.Input();
+            label5 = new AntdUI.Label();
+            iptMaxSource = new AntdUI.Input();
+            label4 = new AntdUI.Label();
+            iptMinSource = new AntdUI.Input();
+            label3 = new AntdUI.Label();
+            iptName = new AntdUI.Input();
+            label2 = new AntdUI.Label();
+            divider2 = new AntdUI.Divider();
+            stackPanel1 = new AntdUI.StackPanel();
+            button_cancel = new AntdUI.Button();
+            button_ok = new AntdUI.Button();
+            divider1 = new AntdUI.Divider();
+            label1 = new AntdUI.Label();
+            panel1.SuspendLayout();
+            stackPanel1.SuspendLayout();
+            SuspendLayout();
+            // 
+            // panel1
+            // 
+            panel1.Controls.Add(sltResultState);
+            panel1.Controls.Add(label7);
+            panel1.Controls.Add(iptMaxArea);
+            panel1.Controls.Add(label6);
+            panel1.Controls.Add(iptMinArea);
+            panel1.Controls.Add(label5);
+            panel1.Controls.Add(iptMaxSource);
+            panel1.Controls.Add(label4);
+            panel1.Controls.Add(iptMinSource);
+            panel1.Controls.Add(label3);
+            panel1.Controls.Add(iptName);
+            panel1.Controls.Add(label2);
+            panel1.Controls.Add(divider2);
+            panel1.Controls.Add(stackPanel1);
+            panel1.Controls.Add(divider1);
+            panel1.Controls.Add(label1);
+            panel1.Dock = DockStyle.Fill;
+            panel1.Location = new Point(0, 0);
+            panel1.Name = "panel1";
+            panel1.Padding = new Padding(12);
+            panel1.Shadow = 6;
+            panel1.Size = new Size(500, 510);
+            panel1.TabIndex = 0;
+            panel1.Text = "panel1";
+            // 
+            // sltResultState
+            // 
+            sltResultState.Dock = DockStyle.Top;
+            sltResultState.Location = new Point(18, 444);
+            sltResultState.Name = "sltResultState";
+            sltResultState.Size = new Size(464, 45);
+            sltResultState.TabIndex = 33;
+            // 
+            // label7
+            // 
+            label7.Dock = DockStyle.Top;
+            label7.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label7.Location = new Point(18, 420);
+            label7.Name = "label7";
+            label7.Size = new Size(464, 24);
+            label7.TabIndex = 32;
+            label7.Text = "结果";
+            // 
+            // iptMaxArea
+            // 
+            iptMaxArea.Dock = DockStyle.Top;
+            iptMaxArea.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            iptMaxArea.Location = new Point(18, 382);
+            iptMaxArea.Name = "iptMaxArea";
+            iptMaxArea.Radius = 3;
+            iptMaxArea.Size = new Size(464, 38);
+            iptMaxArea.TabIndex = 31;
+            // 
+            // label6
+            // 
+            label6.Dock = DockStyle.Top;
+            label6.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label6.Location = new Point(18, 358);
+            label6.Name = "label6";
+            label6.Size = new Size(464, 24);
+            label6.TabIndex = 30;
+            label6.Text = "最大面积";
+            // 
+            // iptMinArea
+            // 
+            iptMinArea.Dock = DockStyle.Top;
+            iptMinArea.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            iptMinArea.Location = new Point(18, 320);
+            iptMinArea.Name = "iptMinArea";
+            iptMinArea.Radius = 3;
+            iptMinArea.Size = new Size(464, 38);
+            iptMinArea.TabIndex = 29;
+            // 
+            // label5
+            // 
+            label5.Dock = DockStyle.Top;
+            label5.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label5.Location = new Point(18, 296);
+            label5.Name = "label5";
+            label5.Size = new Size(464, 24);
+            label5.TabIndex = 28;
+            label5.Text = "最小面积";
+            // 
+            // iptMaxSource
+            // 
+            iptMaxSource.Dock = DockStyle.Top;
+            iptMaxSource.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            iptMaxSource.Location = new Point(18, 258);
+            iptMaxSource.Name = "iptMaxSource";
+            iptMaxSource.Radius = 3;
+            iptMaxSource.Size = new Size(464, 38);
+            iptMaxSource.TabIndex = 27;
+            // 
+            // label4
+            // 
+            label4.Dock = DockStyle.Top;
+            label4.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label4.Location = new Point(18, 234);
+            label4.Name = "label4";
+            label4.Size = new Size(464, 24);
+            label4.TabIndex = 26;
+            label4.Text = "最大得分";
+            // 
+            // iptMinSource
+            // 
+            iptMinSource.Dock = DockStyle.Top;
+            iptMinSource.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            iptMinSource.Location = new Point(18, 196);
+            iptMinSource.Name = "iptMinSource";
+            iptMinSource.Radius = 3;
+            iptMinSource.Size = new Size(464, 38);
+            iptMinSource.TabIndex = 25;
+            // 
+            // label3
+            // 
+            label3.Dock = DockStyle.Top;
+            label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label3.Location = new Point(18, 172);
+            label3.Name = "label3";
+            label3.Size = new Size(464, 24);
+            label3.TabIndex = 24;
+            label3.Text = "最小得分";
+            // 
+            // iptName
+            // 
+            iptName.Dock = DockStyle.Top;
+            iptName.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            iptName.Location = new Point(18, 134);
+            iptName.Name = "iptName";
+            iptName.Radius = 3;
+            iptName.Size = new Size(464, 38);
+            iptName.TabIndex = 23;
+            // 
+            // label2
+            // 
+            label2.Dock = DockStyle.Top;
+            label2.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label2.Location = new Point(18, 110);
+            label2.Name = "label2";
+            label2.Size = new Size(464, 24);
+            label2.TabIndex = 22;
+            label2.Text = "标签名";
+            // 
+            // divider2
+            // 
+            divider2.Dock = DockStyle.Top;
+            divider2.Location = new Point(18, 98);
+            divider2.Name = "divider2";
+            divider2.Size = new Size(464, 12);
+            divider2.TabIndex = 21;
+            // 
+            // stackPanel1
+            // 
+            stackPanel1.Controls.Add(button_cancel);
+            stackPanel1.Controls.Add(button_ok);
+            stackPanel1.Dock = DockStyle.Top;
+            stackPanel1.Location = new Point(18, 54);
+            stackPanel1.Name = "stackPanel1";
+            stackPanel1.RightToLeft = RightToLeft.No;
+            stackPanel1.Size = new Size(464, 44);
+            stackPanel1.TabIndex = 20;
+            stackPanel1.Text = "stackPanel1";
+            // 
+            // button_cancel
+            // 
+            button_cancel.BorderWidth = 1F;
+            button_cancel.Font = new Font("Microsoft YaHei UI", 9F);
+            button_cancel.Ghost = true;
+            button_cancel.Location = new Point(84, 3);
+            button_cancel.Name = "button_cancel";
+            button_cancel.Size = new Size(75, 38);
+            button_cancel.TabIndex = 1;
+            button_cancel.Text = "取消";
+            // 
+            // button_ok
+            // 
+            button_ok.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            button_ok.Location = new Point(3, 3);
+            button_ok.Name = "button_ok";
+            button_ok.Size = new Size(75, 38);
+            button_ok.TabIndex = 0;
+            button_ok.Text = "确定";
+            button_ok.Type = AntdUI.TTypeMini.Primary;
+            // 
+            // divider1
+            // 
+            divider1.Dock = DockStyle.Top;
+            divider1.Location = new Point(18, 42);
+            divider1.Name = "divider1";
+            divider1.Size = new Size(464, 12);
+            divider1.TabIndex = 19;
+            // 
+            // label1
+            // 
+            label1.Dock = DockStyle.Top;
+            label1.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label1.Location = new Point(18, 18);
+            label1.Name = "label1";
+            label1.Size = new Size(464, 24);
+            label1.TabIndex = 17;
+            label1.Text = "标签集合操作";
+            // 
+            // DetectionLableEdit
+            // 
+            Controls.Add(panel1);
+            Name = "DetectionLableEdit";
+            Size = new Size(500, 510);
+            panel1.ResumeLayout(false);
+            stackPanel1.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private AntdUI.Panel panel1;
+        private AntdUI.Label label1;
+        private AntdUI.Input iptName;
+        private AntdUI.Label label2;
+        private AntdUI.Divider divider2;
+        private AntdUI.StackPanel stackPanel1;
+        private AntdUI.Button button_cancel;
+        private AntdUI.Button button_ok;
+        private AntdUI.Divider divider1;
+        private AntdUI.Input iptMaxSource;
+        private AntdUI.Label label4;
+        private AntdUI.Input iptMinSource;
+        private AntdUI.Label label3;
+        private AntdUI.Input iptMaxArea;
+        private AntdUI.Label label6;
+        private AntdUI.Input iptMinArea;
+        private AntdUI.Label label5;
+        private AntdUI.Select sltResultState;
+        private AntdUI.Label label7;
+    }
+}
diff --git a/DHSoftware/Views/DetectionLableEdit.cs b/DHSoftware/Views/DetectionLableEdit.cs
new file mode 100644
index 0000000..01682fd
--- /dev/null
+++ b/DHSoftware/Views/DetectionLableEdit.cs
@@ -0,0 +1,95 @@
+
+
+using System.ComponentModel;
+using System.Reflection;
+using AntdUI;
+using DH.Devices.Vision;
+using static System.Windows.Forms.AxHost;
+
+namespace DHSoftware.Views
+{
+    public partial class DetectionLableEdit : UserControl
+    {
+        private AntdUI.Window window;
+        private DetectionLable  detectionLable;
+        public bool submit;
+        public DetectionLableEdit(AntdUI.Window _window, DetectionLable  detection)
+        {
+            this.window = _window;
+            detectionLable = detection;
+            InitializeComponent();
+            //设置默认值
+            InitData();
+            // 绑定事件
+            BindEventHandler();
+        }
+
+        private void BindEventHandler()
+        {
+            button_ok.Click += Button_ok_Click;
+            button_cancel.Click += Button_cancel_Click;
+        }
+
+        private void Button_cancel_Click(object sender, EventArgs e)
+        {
+            submit = false;
+            this.Dispose();
+        }
+
+        private void Button_ok_Click(object sender, EventArgs e)
+        {
+            iptName.Status = AntdUI.TType.None;
+            //检查输入内容
+            if (String.IsNullOrEmpty(iptName.Text))
+            {
+                iptName.Status = AntdUI.TType.Error;
+                AntdUI.Message.warn(window, "参数名称不能为空!", autoClose: 3);
+                return;
+            }
+            detectionLable.LabelName = iptName.Text;
+            detectionLable.MinSource=Convert.ToDouble(iptMinSource.Text);
+            detectionLable.MaxSource = Convert.ToDouble(iptMaxSource.Text);
+            detectionLable.MinArea = Convert.ToDouble(iptMinArea.Text);
+            detectionLable.MaxArea = Convert.ToDouble(iptMaxArea.Text);
+            ResultState state = EnumHelper.GetEnumFromDescription<ResultState>(sltResultState.Text);
+            detectionLable.ResultState = state;
+            submit = true;
+            this.Dispose();
+        }
+
+        private void InitData()
+        { 
+            // 清空原有项
+            sltResultState.Items.Clear();
+
+            foreach (ResultState state in Enum.GetValues(typeof(ResultState)))
+            {
+                string description = EnumHelper.GetEnumDescription(state);
+                sltResultState.Items.Add(description);
+
+            }
+            if (string.IsNullOrEmpty(detectionLable.LabelName))
+            {
+                iptName.Text = string.Empty;
+                iptMinSource.Text = "0.3";
+                iptMaxSource.Text = "1";
+                iptMinArea.Text = "0";
+                iptMaxArea.Text = "99999999";
+                sltResultState.SelectedIndex = 0;
+
+
+            }
+            else
+            {
+                iptName.Text = detectionLable.LabelName;
+                iptMinSource.Text = detectionLable.MinSource.ToString();
+                iptMaxSource.Text = detectionLable.MaxSource.ToString();
+                iptMinArea.Text =   detectionLable.MinArea.ToString();
+                iptMaxArea.Text =   detectionLable.MaxArea.ToString();
+                sltResultState.Text= EnumHelper.GetEnumDescription(detectionLable.ResultState);
+            }    
+        }
+
+    
+    }
+}
diff --git a/DHSoftware/Views/DetectionLableEdit.resx b/DHSoftware/Views/DetectionLableEdit.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/DHSoftware/Views/DetectionLableEdit.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/DHSoftware/Views/PreTreatEdit.Designer.cs b/DHSoftware/Views/PreTreatEdit.Designer.cs
new file mode 100644
index 0000000..a5af8b4
--- /dev/null
+++ b/DHSoftware/Views/PreTreatEdit.Designer.cs
@@ -0,0 +1,167 @@
+namespace DHSoftware.Views
+{
+    partial class PreTreatEdit
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            panel1 = new AntdUI.Panel();
+            input_value = new AntdUI.InputNumber();
+            label1 = new AntdUI.Label();
+            input_name = new AntdUI.Input();
+            label3 = new AntdUI.Label();
+            divider1 = new AntdUI.Divider();
+            stackPanel1 = new AntdUI.StackPanel();
+            button_cancel = new AntdUI.Button();
+            button_ok = new AntdUI.Button();
+            panel1.SuspendLayout();
+            stackPanel1.SuspendLayout();
+            SuspendLayout();
+            // 
+            // panel1
+            // 
+            panel1.Controls.Add(input_value);
+            panel1.Controls.Add(label1);
+            panel1.Controls.Add(input_name);
+            panel1.Controls.Add(label3);
+            panel1.Controls.Add(divider1);
+            panel1.Controls.Add(stackPanel1);
+            panel1.Dock = DockStyle.Fill;
+            panel1.Location = new Point(0, 0);
+            panel1.Name = "panel1";
+            panel1.Padding = new Padding(12);
+            panel1.Shadow = 6;
+            panel1.Size = new Size(500, 220);
+            panel1.TabIndex = 0;
+            panel1.Text = "panel1";
+            // 
+            // input_value
+            // 
+            input_value.Dock = DockStyle.Top;
+            input_value.Font = new Font("Microsoft YaHei UI", 9F);
+            input_value.Location = new Point(18, 160);
+            input_value.Maximum = new decimal(new int[] { 200, 0, 0, 0 });
+            input_value.Minimum = new decimal(new int[] { 0, 0, 0, 0 });
+            input_value.Name = "input_value";
+            input_value.Radius = 3;
+            input_value.Size = new Size(464, 38);
+            input_value.TabIndex = 18;
+            input_value.Text = "0";
+            // 
+            // label1
+            // 
+            label1.Dock = DockStyle.Top;
+            label1.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label1.Location = new Point(18, 136);
+            label1.Name = "label1";
+            label1.Size = new Size(464, 24);
+            label1.TabIndex = 17;
+            label1.Text = "参数值";
+            // 
+            // input_name
+            // 
+            input_name.Dock = DockStyle.Top;
+            input_name.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            input_name.Location = new Point(18, 98);
+            input_name.Name = "input_name";
+            input_name.Radius = 3;
+            input_name.Size = new Size(464, 38);
+            input_name.TabIndex = 16;
+            // 
+            // label3
+            // 
+            label3.Dock = DockStyle.Top;
+            label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            label3.Location = new Point(18, 74);
+            label3.Name = "label3";
+            label3.Size = new Size(464, 24);
+            label3.TabIndex = 15;
+            label3.Text = "参数名称";
+            // 
+            // divider1
+            // 
+            divider1.Dock = DockStyle.Top;
+            divider1.Location = new Point(18, 62);
+            divider1.Name = "divider1";
+            divider1.Size = new Size(464, 12);
+            divider1.TabIndex = 14;
+            // 
+            // stackPanel1
+            // 
+            stackPanel1.Controls.Add(button_cancel);
+            stackPanel1.Controls.Add(button_ok);
+            stackPanel1.Dock = DockStyle.Top;
+            stackPanel1.Location = new Point(18, 18);
+            stackPanel1.Name = "stackPanel1";
+            stackPanel1.RightToLeft = RightToLeft.No;
+            stackPanel1.Size = new Size(464, 44);
+            stackPanel1.TabIndex = 3;
+            stackPanel1.Text = "stackPanel1";
+            // 
+            // button_cancel
+            // 
+            button_cancel.BorderWidth = 1F;
+            button_cancel.Font = new Font("Microsoft YaHei UI", 9F);
+            button_cancel.Ghost = true;
+            button_cancel.Location = new Point(84, 3);
+            button_cancel.Name = "button_cancel";
+            button_cancel.Size = new Size(75, 38);
+            button_cancel.TabIndex = 1;
+            button_cancel.Text = "取消";
+            // 
+            // button_ok
+            // 
+            button_ok.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+            button_ok.Location = new Point(3, 3);
+            button_ok.Name = "button_ok";
+            button_ok.Size = new Size(75, 38);
+            button_ok.TabIndex = 0;
+            button_ok.Text = "确定";
+            button_ok.Type = AntdUI.TTypeMini.Primary;
+            // 
+            // PreTreatEdit
+            // 
+            Controls.Add(panel1);
+            Name = "PreTreatEdit";
+            Size = new Size(500, 220);
+            panel1.ResumeLayout(false);
+            stackPanel1.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private AntdUI.Panel panel1;
+        private AntdUI.StackPanel stackPanel1;
+        private AntdUI.Button button_cancel;
+        private AntdUI.Button button_ok;
+        private AntdUI.Divider divider1;
+        private AntdUI.Label label1;
+        private AntdUI.Input input_name;
+        private AntdUI.Label label3;
+        private AntdUI.InputNumber input_value;
+    }
+}
diff --git a/DHSoftware/Views/PreTreatEdit.cs b/DHSoftware/Views/PreTreatEdit.cs
new file mode 100644
index 0000000..450b958
--- /dev/null
+++ b/DHSoftware/Views/PreTreatEdit.cs
@@ -0,0 +1,57 @@
+
+
+using DH.Devices.Vision;
+
+namespace DHSoftware.Views
+{
+    public partial class PreTreatEdit : UserControl
+    {
+        private AntdUI.Window window;
+        private PreTreatParam PreTreat;
+        public bool submit;
+        public PreTreatEdit(AntdUI.Window _window, PreTreatParam preTreat)
+        {
+            this.window = _window;
+            PreTreat = preTreat;
+            InitializeComponent();
+            //设置默认值
+            InitData();
+            // 绑定事件
+            BindEventHandler();
+        }
+
+        private void BindEventHandler()
+        {
+            button_ok.Click += Button_ok_Click;
+            button_cancel.Click += Button_cancel_Click;
+        }
+
+        private void Button_cancel_Click(object sender, EventArgs e)
+        {
+            submit = false;
+            this.Dispose();
+        }
+
+        private void Button_ok_Click(object sender, EventArgs e)
+        {
+            input_name.Status = AntdUI.TType.None;
+            //检查输入内容
+            if (String.IsNullOrEmpty(input_name.Text))
+            {
+                input_name.Status = AntdUI.TType.Error;
+                AntdUI.Message.warn(window, "参数名称不能为空!", autoClose: 3);
+                return;
+            }
+            PreTreat.Name = input_name.Text;
+            PreTreat.Value = input_value.Value.ToString();
+            submit = true;
+            this.Dispose();
+        }
+
+        private void InitData()
+        {
+            input_name.Text = PreTreat.Name;
+            input_value.Value = Convert.ToDecimal(PreTreat.Value);
+        }
+    }
+}
diff --git a/DHSoftware/Views/PreTreatEdit.resx b/DHSoftware/Views/PreTreatEdit.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/DHSoftware/Views/PreTreatEdit.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/DHSoftware/Views/PreTreatUserControl.Designer.cs b/DHSoftware/Views/PreTreatUserControl.Designer.cs
index c0aaca8..292a115 100644
--- a/DHSoftware/Views/PreTreatUserControl.Designer.cs
+++ b/DHSoftware/Views/PreTreatUserControl.Designer.cs
@@ -54,6 +54,7 @@
             btnPreOpen.Size = new Size(46, 23);
             btnPreOpen.TabIndex = 21;
             btnPreOpen.Text = "...";
+            btnPreOpen.Click += btnPreOpen_Click;
             // 
             // tbxPrePath
             // 
diff --git a/DHSoftware/Views/PreTreatUserControl.cs b/DHSoftware/Views/PreTreatUserControl.cs
index b99d13c..6b20868 100644
--- a/DHSoftware/Views/PreTreatUserControl.cs
+++ b/DHSoftware/Views/PreTreatUserControl.cs
@@ -16,5 +16,10 @@ namespace DHSoftware.Views
         {
             InitializeComponent();
         }
+
+        private void btnPreOpen_Click(object sender, EventArgs e)
+        {
+
+        }
     }
 }
diff --git a/DHSoftware/Views/PreTreatUserControl.resx b/DHSoftware/Views/PreTreatUserControl.resx
index af32865..8b2ff64 100644
--- a/DHSoftware/Views/PreTreatUserControl.resx
+++ b/DHSoftware/Views/PreTreatUserControl.resx
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <root>
   <!--
-    Microsoft ResX Schema 
+    Microsoft ResX Schema
 
     Version 2.0
 
@@ -48,7 +48,7 @@
     value   : The object must be serialized with
             : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
-    
+
     mimetype: application/x-microsoft.net.object.soap.base64
     value   : The object must be serialized with
             : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
diff --git a/DHSoftware/Views/SettingWindow.Designer.cs b/DHSoftware/Views/SettingWindow.Designer.cs
new file mode 100644
index 0000000..b99c98d
--- /dev/null
+++ b/DHSoftware/Views/SettingWindow.Designer.cs
@@ -0,0 +1,138 @@
+namespace DHSoftware.Views
+{
+    partial class SettingWindow
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            panel3 = new AntdUI.Panel();
+            panel1 = new AntdUI.Panel();
+            panel2 = new AntdUI.Panel();
+            btnAdd = new AntdUI.Button();
+            menu1 = new AntdUI.Menu();
+            pageHeader1 = new AntdUI.PageHeader();
+            panel3.SuspendLayout();
+            panel1.SuspendLayout();
+            panel2.SuspendLayout();
+            SuspendLayout();
+            // 
+            // panel3
+            // 
+            panel3.Controls.Add(panel1);
+            panel3.Controls.Add(pageHeader1);
+            panel3.Dock = DockStyle.Fill;
+            panel3.Location = new Point(0, 0);
+            panel3.Name = "panel3";
+            panel3.Size = new Size(838, 561);
+            panel3.TabIndex = 1;
+            panel3.Text = "panel3";
+            // 
+            // panel1
+            // 
+            panel1.Controls.Add(panel2);
+            panel1.Controls.Add(menu1);
+            panel1.Dock = DockStyle.Left;
+            panel1.Location = new Point(0, 33);
+            panel1.Name = "panel1";
+            panel1.Size = new Size(141, 528);
+            panel1.TabIndex = 2;
+            panel1.Text = "panel1";
+            // 
+            // panel2
+            // 
+            panel2.Back = SystemColors.Window;
+            panel2.BackColor = SystemColors.Window;
+            panel2.Controls.Add(btnAdd);
+            panel2.Dock = DockStyle.Fill;
+            panel2.Location = new Point(0, 497);
+            panel2.Name = "panel2";
+            panel2.Size = new Size(141, 31);
+            panel2.TabIndex = 1;
+            panel2.Text = "panel2";
+            // 
+            // btnAdd
+            // 
+            btnAdd.BackActive = SystemColors.Control;
+            btnAdd.BackColor = SystemColors.Control;
+            btnAdd.Dock = DockStyle.Left;
+            btnAdd.ForeColor = Color.Black;
+            btnAdd.IconRatio = 1F;
+            btnAdd.IconSvg = "AppstoreAddOutlined";
+            btnAdd.Location = new Point(0, 0);
+            btnAdd.Name = "btnAdd";
+            btnAdd.Size = new Size(35, 31);
+            btnAdd.TabIndex = 1;
+            btnAdd.Click += btnAdd_Click;
+            // 
+            // menu1
+            // 
+            menu1.BackColor = SystemColors.Window;
+            menu1.Dock = DockStyle.Top;
+            menu1.Location = new Point(0, 0);
+            menu1.Name = "menu1";
+            menu1.Size = new Size(141, 497);
+            menu1.TabIndex = 0;
+            menu1.Text = "menu1";
+            menu1.MouseClick += menu1_MouseClick;
+            menu1.MouseDown += Menu_MouseDown;
+            // 
+            // pageHeader1
+            // 
+            pageHeader1.BackColor = SystemColors.MenuHighlight;
+            pageHeader1.Dock = DockStyle.Top;
+            pageHeader1.Location = new Point(0, 0);
+            pageHeader1.Mode = AntdUI.TAMode.Dark;
+            pageHeader1.Name = "pageHeader1";
+            pageHeader1.ShowButton = true;
+            pageHeader1.ShowIcon = true;
+            pageHeader1.Size = new Size(838, 33);
+            pageHeader1.TabIndex = 1;
+            pageHeader1.Text = "设置";
+            // 
+            // SettingWindow
+            // 
+            AutoScaleDimensions = new SizeF(7F, 17F);
+            AutoScaleMode = AutoScaleMode.Font;
+            ClientSize = new Size(838, 561);
+            Controls.Add(panel3);
+            Name = "SettingWindow";
+            StartPosition = FormStartPosition.CenterScreen;
+            Text = "SettingWinform";
+            panel3.ResumeLayout(false);
+            panel1.ResumeLayout(false);
+            panel2.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+        private AntdUI.Panel panel3;
+        private AntdUI.PageHeader pageHeader1;
+        private AntdUI.Panel panel1;
+        private AntdUI.Panel panel2;
+        private AntdUI.Button btnAdd;
+        private AntdUI.Menu menu1;
+    }
+}
\ No newline at end of file
diff --git a/DHSoftware/Views/SettingWindow.cs b/DHSoftware/Views/SettingWindow.cs
new file mode 100644
index 0000000..9a4e194
--- /dev/null
+++ b/DHSoftware/Views/SettingWindow.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using AntdUI;
+
+namespace DHSoftware.Views
+{
+    public partial class SettingWindow : Window
+    {
+        public SettingWindow()
+        {
+            InitializeComponent();
+
+            AntdUI.TooltipComponent tooltip = new AntdUI.TooltipComponent()
+            {
+                Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134))),
+            };
+            tooltip.ArrowAlign = AntdUI.TAlign.Right;
+            tooltip.SetTip(btnAdd, "新增工位");
+
+
+         
+        }
+
+        private void Menu_MouseDown(object sender, MouseEventArgs e)
+        {
+            if (e.Button == MouseButtons.Right)
+            {
+                // 转换坐标到控件内部坐标系(考虑滚动条)
+                Point clickPoint = new Point(e.X, e.Y + menu1.ScrollBar.Value);
+
+                // 递归查找命中的菜单项
+                MenuItem clickedItem = FindClickedItem(menu1.Items, clickPoint);
+
+                if (clickedItem != null)
+                {
+                    // 显示节点名称弹窗
+                    //MessageBox.Show($"右键点击的节点: {clickedItem.Text}");
+                
+                    var menulist = new AntdUI.IContextMenuStripItem[]
+                    {
+                    new AntdUI.ContextMenuStripItem("关联相机", "")
+                        {
+                            IconSvg = "VideoCameraAddOutlined"
+                        }
+                    };
+                    AntdUI.ContextMenuStrip.open(menu1, it =>
+                    {
+                        if (it.Text == "关联相机")
+                        {
+                            using (var dlg = new AddCameraWindow())
+                            {
+                                if (dlg.ShowDialog() == DialogResult.OK)
+                                {
+                                    var newItem = new MenuItem(dlg.CubicleName);
+                                    newItem.IconSvg = "VideoCameraOutlined";
+                                    //// 防止重复添加
+                                    //if (!menu1.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
+                                    //{
+                                    clickedItem.Sub.Add(newItem);
+                                    //}
+                                    //else
+                                    //{
+                                    //    AntdUI.Notification.warn(this, "新增失败", $"{dlg.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
+                                    //}
+                                }
+                            }
+                        }
+                    }, menulist);
+                }
+            }
+        }
+
+        private MenuItem FindClickedItem(MenuItemCollection items, Point clickPoint)
+        {
+            foreach (MenuItem item in items)
+            {
+                // 检查当前项是否可见且包含点击坐标
+                if (item.Visible && item.Rect.Contains(clickPoint))
+                {
+                    return item;
+                }
+
+                // 递归检查子项(如果展开)
+                if (item.Expand && item.Sub != null)
+                {
+                    var childResult = FindClickedItem(item.Sub, clickPoint);
+                    if (childResult != null) return childResult;
+                }
+            }
+            return null;
+        }
+
+        private void btnAdd_Click(object sender, EventArgs e)
+        {
+            using (var dlg = new AddCubicleWindow())
+            {
+                if (dlg.ShowDialog() == DialogResult.OK)
+                {
+                    var newItem = new MenuItem(dlg.CubicleName);
+                    newItem.IconSvg = "AppstoreOutlined";
+                    // 防止重复添加
+                    if (!menu1.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
+                    {
+                        menu1.Items.Add(newItem);
+                    }
+                    else
+                    {
+                        AntdUI.Notification.warn(this, "新增工位失败", $"{dlg.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
+                    }
+                }
+            }
+        }
+
+        private void menu1_MouseClick(object sender, MouseEventArgs e)
+        {
+            //if (e.Button == MouseButtons.Right)
+            //{ 
+            //    var menu =sender as Menu;
+            //    if (menu?.Items.Count == 0)
+            //    {
+            //        return;
+            //    }
+
+            //}
+       }
+    }
+}
+
diff --git a/DHSoftware/Views/SettingWindow.resx b/DHSoftware/Views/SettingWindow.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/DHSoftware/Views/SettingWindow.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/DHSoftware/Views/SettingWindow1.Designer.cs b/DHSoftware/Views/SettingWindow1.Designer.cs
new file mode 100644
index 0000000..75929e5
--- /dev/null
+++ b/DHSoftware/Views/SettingWindow1.Designer.cs
@@ -0,0 +1,181 @@
+namespace DHSoftware.Views
+{
+    partial class SettingWindow1
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            AntdUI.MenuItem menuItem1 = new AntdUI.MenuItem();
+            AntdUI.MenuItem menuItem2 = new AntdUI.MenuItem();
+            AntdUI.MenuItem menuItem3 = new AntdUI.MenuItem();
+            AntdUI.Tabs.StyleCard styleCard1 = new AntdUI.Tabs.StyleCard();
+            pageHeader1 = new AntdUI.PageHeader();
+            panel1 = new AntdUI.Panel();
+            panel2 = new AntdUI.Panel();
+            btnAdd = new AntdUI.Button();
+            menu1 = new AntdUI.Menu();
+            panel3 = new AntdUI.Panel();
+            tabs1 = new AntdUI.Tabs();
+            divider1 = new AntdUI.Divider();
+            panel1.SuspendLayout();
+            panel2.SuspendLayout();
+            panel3.SuspendLayout();
+            SuspendLayout();
+            // 
+            // pageHeader1
+            // 
+            pageHeader1.BackColor = SystemColors.MenuHighlight;
+            pageHeader1.Dock = DockStyle.Top;
+            pageHeader1.Location = new Point(0, 0);
+            pageHeader1.Mode = AntdUI.TAMode.Dark;
+            pageHeader1.Name = "pageHeader1";
+            pageHeader1.ShowButton = true;
+            pageHeader1.ShowIcon = true;
+            pageHeader1.Size = new Size(1042, 33);
+            pageHeader1.TabIndex = 1;
+            pageHeader1.Text = "设置";
+            // 
+            // panel1
+            // 
+            panel1.Controls.Add(panel2);
+            panel1.Controls.Add(menu1);
+            panel1.Dock = DockStyle.Left;
+            panel1.Location = new Point(0, 33);
+            panel1.Name = "panel1";
+            panel1.Size = new Size(141, 666);
+            panel1.TabIndex = 2;
+            panel1.Text = "panel1";
+            // 
+            // panel2
+            // 
+            panel2.Back = SystemColors.Window;
+            panel2.BackColor = SystemColors.Window;
+            panel2.Controls.Add(btnAdd);
+            panel2.Dock = DockStyle.Fill;
+            panel2.Location = new Point(0, 497);
+            panel2.Name = "panel2";
+            panel2.Size = new Size(141, 169);
+            panel2.TabIndex = 1;
+            panel2.Text = "panel2";
+            // 
+            // btnAdd
+            // 
+            btnAdd.BackActive = SystemColors.Control;
+            btnAdd.BackColor = SystemColors.Control;
+            btnAdd.Dock = DockStyle.Bottom;
+            btnAdd.ForeColor = Color.Black;
+            btnAdd.IconRatio = 1F;
+            btnAdd.IconSvg = "AppstoreAddOutlined";
+            btnAdd.Location = new Point(0, 138);
+            btnAdd.Name = "btnAdd";
+            btnAdd.Size = new Size(141, 31);
+            btnAdd.TabIndex = 1;
+            btnAdd.Click += btnAdd_Click;
+            // 
+            // menu1
+            // 
+            menu1.BackColor = SystemColors.Window;
+            menu1.Dock = DockStyle.Top;
+            menuItem1.IconSvg = "VideoCameraOutlined";
+            menuItem1.Text = "相机设置";
+            menuItem2.IconSvg = "AppstoreOutlined";
+            menuItem2.Text = "工位设置";
+            menuItem3.IconSvg = "ControlOutlined";
+            menuItem3.Text = "运控设置";
+            menu1.Items.Add(menuItem1);
+            menu1.Items.Add(menuItem2);
+            menu1.Items.Add(menuItem3);
+            menu1.Location = new Point(0, 0);
+            menu1.Name = "menu1";
+            menu1.Size = new Size(141, 497);
+            menu1.TabIndex = 0;
+            menu1.Text = "menu1";
+            menu1.MouseDown += menu1_MouseDown;
+            // 
+            // panel3
+            // 
+            panel3.Controls.Add(tabs1);
+            panel3.Controls.Add(divider1);
+            panel3.Controls.Add(panel1);
+            panel3.Controls.Add(pageHeader1);
+            panel3.Dock = DockStyle.Fill;
+            panel3.Location = new Point(0, 0);
+            panel3.Name = "panel3";
+            panel3.Size = new Size(1042, 699);
+            panel3.TabIndex = 1;
+            panel3.Text = "panel3";
+            // 
+            // tabs1
+            // 
+            tabs1.BackColor = SystemColors.Window;
+            tabs1.Dock = DockStyle.Fill;
+            tabs1.Location = new Point(151, 33);
+            tabs1.Name = "tabs1";
+            tabs1.Size = new Size(891, 666);
+            tabs1.Style = styleCard1;
+            tabs1.TabIndex = 5;
+            tabs1.Text = "tabs1";
+            tabs1.Type = AntdUI.TabType.Card;
+            // 
+            // divider1
+            // 
+            divider1.BackColor = SystemColors.Window;
+            divider1.Dock = DockStyle.Left;
+            divider1.Location = new Point(141, 33);
+            divider1.Name = "divider1";
+            divider1.OrientationMargin = 0F;
+            divider1.Size = new Size(10, 666);
+            divider1.TabIndex = 4;
+            divider1.Text = "";
+            divider1.Vertical = true;
+            // 
+            // SettingWindow1
+            // 
+            AutoScaleDimensions = new SizeF(7F, 17F);
+            AutoScaleMode = AutoScaleMode.Font;
+            ClientSize = new Size(1042, 699);
+            Controls.Add(panel3);
+            Name = "SettingWindow1";
+            StartPosition = FormStartPosition.CenterScreen;
+            Text = "SettingWinform";
+            panel1.ResumeLayout(false);
+            panel2.ResumeLayout(false);
+            panel3.ResumeLayout(false);
+            ResumeLayout(false);
+        }
+
+        #endregion
+
+        private AntdUI.PageHeader pageHeader1;
+        private AntdUI.Panel panel1;
+        private AntdUI.Panel panel2;
+        private AntdUI.Button btnAdd;
+        private AntdUI.Menu menu1;
+        private AntdUI.Panel panel3;
+        private AntdUI.Tabs tabs1;
+        private AntdUI.Divider divider1;
+    }
+}
\ No newline at end of file
diff --git a/DHSoftware/Views/SettingWindow1.cs b/DHSoftware/Views/SettingWindow1.cs
new file mode 100644
index 0000000..2429b38
--- /dev/null
+++ b/DHSoftware/Views/SettingWindow1.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using AntdUI;
+namespace DHSoftware.Views
+{
+    public partial class SettingWindow1 : Window
+    {
+        private UserControl currControl;
+        public SettingWindow1()
+        {
+            InitializeComponent();
+
+            AntdUI.TooltipComponent tooltip = new AntdUI.TooltipComponent()
+            {
+                Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134))),
+            };
+            tooltip.ArrowAlign = AntdUI.TAlign.Right;
+            tooltip.SetTip(btnAdd, "新增工位");
+
+
+
+        }
+
+
+
+        private void btnAdd_Click(object sender, EventArgs e)
+        {
+            // 查找工位设置项
+            var workstationItem = FindMenuItem(menu1.Items, "工位设置");
+
+            if (workstationItem != null)
+            {
+                using (var dlg = new AddCubicleWindow())
+                {
+                    if (dlg.ShowDialog() == DialogResult.OK)
+                    {
+
+                        AddSubItem(workstationItem, dlg.CubicleName);
+
+                    }
+                    else
+                    {
+                        AntdUI.Notification.error(this, "操作失败", "未找到工位设置项", TAlignFrom.TR);
+                    }
+                }
+            }
+        }
+        // 递归查找菜单项
+        private MenuItem FindMenuItem(MenuItemCollection items, string targetText)
+        {
+            foreach (MenuItem item in items)
+            {
+                if (item.Text == targetText) return item;
+                if (item.Sub != null)
+                {
+                    var subResult = FindMenuItem(item.Sub, targetText);
+                    if (subResult != null) return subResult;
+                }
+            }
+            return null;
+        }
+
+        // 添加子项方法
+        private void AddSubItem(MenuItem parentItem, string cubicleName)
+        {
+            // 创建带图标的菜单项
+            var newItem = new MenuItem(cubicleName)
+            {
+                IconSvg = "AppstoreOutlined",
+                Tag = Guid.NewGuid() // 添加唯一标识
+            };
+
+            // 检查重复项(根据名称和ID)
+            if (!parentItem.Sub.Cast<MenuItem>().Any(m =>
+                m.Text == cubicleName &&
+                m.Tag?.ToString() == newItem.Tag.ToString()))
+            {
+                parentItem.Sub.Add(newItem);
+
+                // 自动展开父项
+                if (!parentItem.Expand) parentItem.Expand = true;
+
+                // 刷新菜单布局
+
+                menu1.Invalidate();
+            }
+            else
+            {
+                AntdUI.Notification.warn(this, "添加失败", "工位名称已存在", TAlignFrom.TR);
+            }
+        }
+
+        bool isUpdatingTabs = false;
+  
+
+        private void menu1_MouseDown(object sender, MouseEventArgs e)
+        {
+            // 转换坐标到控件内部坐标系(考虑滚动条)
+            Point clickPoint = new Point(e.X, e.Y + menu1.ScrollBar.Value);
+
+            // 递归查找命中的菜单项
+            MenuItem clickedItem = FindClickedItem(menu1.Items, clickPoint);
+
+            if (clickedItem != null)
+            {
+                if (clickedItem.PARENTITEM == null)
+                {
+                    return;
+                }
+
+                switch (clickedItem.PARENTITEM.Text) 
+                {
+                    case "相机设置":
+
+                        break;
+                    case "工位设置":
+                        // 检查是否已存在同名 TabPage
+                        foreach (var tab in tabs1.Pages)
+                        {
+                            if (tab is AntdUI.TabPage existingTab && existingTab.Text == $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}")
+                            {
+                                isUpdatingTabs = true;
+                                tabs1.SelectedTab = existingTab; // 直接跳转到已存在的 TabPage
+                                isUpdatingTabs = false;
+                                currControl = existingTab.Controls.Count > 0 ? existingTab.Controls[0] as UserControl : null;
+                                return;
+                            }
+                        }
+
+                        UserControl control = null;
+                        control = new DetectControl(this);
+                        if (control != null)
+                        {
+                            //容器添加控件,需要调整dpi
+                            control.Dock = DockStyle.Fill;
+                            AutoDpi(control);
+                            AntdUI.TabPage tabPage = new AntdUI.TabPage()
+                            {
+                                Text = $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}",
+                            };
+                            tabPage.Controls.Add(control);
+                            tabs1.Pages.Add(tabPage);
+                            isUpdatingTabs = true;
+                            tabs1.SelectedTab = tabPage;
+                            isUpdatingTabs = false;
+                            currControl = control;
+                        }
+                        break;
+
+                    case "运控设置":
+
+                        break;
+                
+                
+                }
+            }
+            }
+
+
+        private MenuItem FindClickedItem(MenuItemCollection items, Point clickPoint)
+        {
+            foreach (MenuItem item in items)
+            {
+                // 检查当前项是否可见且包含点击坐标
+                if (item.Visible && item.Rect.Contains(clickPoint))
+                {
+                    return item;
+                }
+
+                // 递归检查子项(如果展开)
+                if (item.Expand && item.Sub != null)
+                {
+                    var childResult = FindClickedItem(item.Sub, clickPoint);
+                    if (childResult != null) return childResult;
+                }
+            }
+            return null;
+        }
+    }
+}
+
diff --git a/DHSoftware/Views/SettingWindow1.resx b/DHSoftware/Views/SettingWindow1.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/DHSoftware/Views/SettingWindow1.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/DHSoftware/Views/UserConfigFrm.resx b/DHSoftware/Views/UserConfigFrm.resx
index af32865..8b2ff64 100644
--- a/DHSoftware/Views/UserConfigFrm.resx
+++ b/DHSoftware/Views/UserConfigFrm.resx
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <root>
   <!--
-    Microsoft ResX Schema 
+    Microsoft ResX Schema
 
     Version 2.0
 
@@ -48,7 +48,7 @@
     value   : The object must be serialized with
             : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
-    
+
     mimetype: application/x-microsoft.net.object.soap.base64
     value   : The object must be serialized with
             : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
diff --git a/DHSoftware/Views/​MotionControl.Designer.cs b/DHSoftware/Views/​MotionControl.Designer.cs
new file mode 100644
index 0000000..49cac7e
--- /dev/null
+++ b/DHSoftware/Views/​MotionControl.Designer.cs
@@ -0,0 +1,44 @@
+namespace DHSoftware.Views
+{
+    partial class _​MotionControl
+    {
+        /// <summary> 
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region 组件设计器生成的代码
+
+        /// <summary> 
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            SuspendLayout();
+            // 
+            // _MotionControl
+            // 
+            AutoScaleDimensions = new SizeF(7F, 17F);
+            AutoScaleMode = AutoScaleMode.Font;
+            Name = "_MotionControl";
+            Size = new Size(782, 481);
+            ResumeLayout(false);
+        }
+
+        #endregion
+    }
+}
diff --git a/DHSoftware/Views/​MotionControl.cs b/DHSoftware/Views/​MotionControl.cs
new file mode 100644
index 0000000..98aec49
--- /dev/null
+++ b/DHSoftware/Views/​MotionControl.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace DHSoftware.Views
+{
+    public partial class _​MotionControl : UserControl
+    {
+        public _​MotionControl()
+        {
+            InitializeComponent();
+        }
+    }
+}
diff --git a/DHSoftware/Views/​MotionControl.resx b/DHSoftware/Views/​MotionControl.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/DHSoftware/Views/​MotionControl.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file