From 40014e6e41f1ec017a07b7a620b3c700807d0519 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期日, 23 三月 2025 13:51:00 +0800
Subject: [PATCH] 新增DOControl

---
 Plugin.DOControl/packages.config                  |    6 
 WPFProject/Lang/zh-CN/ServoManage.json            |   41 
 Plugin.TsExecution/Plugin.TsExecution.csproj      |    4 
 HMI.IOMonitor/packages.config                     |    2 
 Plugin.DOControl/DOControl.xaml                   |  112 ++
 HMI.ParameterManage/HMI.ParameterManage.csproj    |    4 
 Plugin.ServoManage/ServoModal.xaml.cs             |  126 ++
 Plugin.DOControl/Properties/Settings.settings     |    7 
 HMI.DataViewer/HMI.DataViewer.csproj              |    4 
 Plugin.ServoManage/Entity/ServoProductData.cs     |   14 
 HMI.LogViewer/HMI.LogViewer.csproj                |    4 
 HMI.UI/Converter/VisibilityBoolConverter.cs       |    6 
 Plugin.ServoManage/Plugin.ServoManage.csproj      |   45 
 Plugin.ServoManage/packages.config                |    2 
 HMI.ParameterManage/packages.config               |    2 
 WPFProject/App.config                             |    2 
 HMI.UnitTest/packages.config                      |    2 
 Plugin.ServoManage/ServoManage.xaml.cs            |  707 +++++++++++++++
 Plugin.ServoManage/ServoProductModal.xaml         |   34 
 Plugin.TsExecution/TsExecution.xaml.cs            |   10 
 Plugin.DOControl/Properties/Resources.Designer.cs |   62 +
 Plugin.TsExecution/TsExecution.xaml               |   13 
 WPFProject/packages.config                        |    2 
 HMI.UI/Style/MsgBoxStyle.xaml                     |    3 
 Plugin.DOControl/Properties/AssemblyInfo.cs       |   52 +
 HMI.LogViewer/packages.config                     |    2 
 Plugin.ServoManage/ServoModal.xaml                |   37 
 HMI.AlermInfoManage/packages.config               |    2 
 Plugin.ServoManage/NumberPanel.xaml.cs            |  160 +++
 Plugin.TsExecution/packages.config                |    2 
 WPFProject/Lang/en-US/ServoManage.json            |   45 
 HMI.UI/packages.config                            |    2 
 HMI.UI/Style/FormStyle.xaml                       |    2 
 WPFProject/WPFProject.csproj                      |    7 
 HMI.SettingControl/packages.config                |    2 
 HMI.IOMonitor/HMI.IOMonitor.csproj                |    4 
 HMI.UI/Custom/NumberInput.cs                      |   98 ++
 HMI.UI/Style/PanuonResource.xaml                  |    2 
 WPFProject/PanuonWindow.xaml                      |    1 
 Plugin.ServoManage/ServoManage.xaml               |  446 ++++++---
 Plugin.ServoManage/ServoSetting.xaml              |   10 
 HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj    |    4 
 Plugin.DOControl/Plugin.DOControl.csproj          |  113 ++
 WPFProject/WPFProject.sln                         |   20 
 HMI.MenuManage/packages.config                    |    2 
 HMI.MenuManage/HMI.MenuManage.csproj              |    4 
 HMI.SettingControl/HMI.SettingControl.csproj      |    4 
 Plugin.TestResult/Plugin.TestResult.csproj        |    4 
 HMI.UI/DpUtil/FormGroupHelper.cs                  |    2 
 Plugin.ServoManage/ServoSetting.xaml.cs           |   28 
 Plugin.DOControl/Properties/Resources.resx        |  117 ++
 Plugin.DOControl/Properties/Settings.Designer.cs  |   30 
 Plugin.ServoManage/Entity/ServoData.cs            |   15 
 Plugin.DOControl/DOControl.xaml.cs                |   46 +
 /dev/null                                         |    0 
 Plugin.TestResult/packages.config                 |    2 
 HMI.DataViewer/packages.config                    |    2 
 Plugin.ServoManage/NumberPanel.xaml               |   78 +
 HMI.UnitTest/HMI.UnitTest.csproj                  |    4 
 Plugin.ServoManage/ServoProductModal.xaml.cs      |  138 +++
 HMI.UI/HMI.UI.csproj                              |    5 
 61 files changed, 2,496 insertions(+), 210 deletions(-)

diff --git a/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj b/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
index 48cdbd1..452376a 100644
--- a/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
+++ b/HMI.AlermInfoManage/HMI.AlarmInfoManage.csproj
@@ -71,8 +71,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="SimensDriver">
       <HintPath>..\Libs\SimensDriver.dll</HintPath>
diff --git a/HMI.AlermInfoManage/packages.config b/HMI.AlermInfoManage/packages.config
index 6adf3c1..467c193 100644
--- a/HMI.AlermInfoManage/packages.config
+++ b/HMI.AlermInfoManage/packages.config
@@ -3,6 +3,6 @@
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="NPOI" version="2.4.1" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
   <package id="SharpZipLib" version="1.0.0" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.DataViewer/HMI.DataViewer.csproj b/HMI.DataViewer/HMI.DataViewer.csproj
index 7cd4470..20ee612 100644
--- a/HMI.DataViewer/HMI.DataViewer.csproj
+++ b/HMI.DataViewer/HMI.DataViewer.csproj
@@ -71,8 +71,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
diff --git a/HMI.DataViewer/packages.config b/HMI.DataViewer/packages.config
index 6adf3c1..467c193 100644
--- a/HMI.DataViewer/packages.config
+++ b/HMI.DataViewer/packages.config
@@ -3,6 +3,6 @@
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="NPOI" version="2.4.1" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
   <package id="SharpZipLib" version="1.0.0" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.IOMonitor/HMI.IOMonitor.csproj b/HMI.IOMonitor/HMI.IOMonitor.csproj
index d14ddca..c048582 100644
--- a/HMI.IOMonitor/HMI.IOMonitor.csproj
+++ b/HMI.IOMonitor/HMI.IOMonitor.csproj
@@ -74,8 +74,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="SimensDriver">
       <HintPath>..\Libs\SimensDriver.dll</HintPath>
diff --git a/HMI.IOMonitor/packages.config b/HMI.IOMonitor/packages.config
index 6adf3c1..467c193 100644
--- a/HMI.IOMonitor/packages.config
+++ b/HMI.IOMonitor/packages.config
@@ -3,6 +3,6 @@
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="NPOI" version="2.4.1" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
   <package id="SharpZipLib" version="1.0.0" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.LogViewer/HMI.LogViewer.csproj b/HMI.LogViewer/HMI.LogViewer.csproj
index 4d44e26..8eb4d95 100644
--- a/HMI.LogViewer/HMI.LogViewer.csproj
+++ b/HMI.LogViewer/HMI.LogViewer.csproj
@@ -56,8 +56,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
diff --git a/HMI.LogViewer/packages.config b/HMI.LogViewer/packages.config
index 21b491c..c3ebe09 100644
--- a/HMI.LogViewer/packages.config
+++ b/HMI.LogViewer/packages.config
@@ -2,5 +2,5 @@
 <packages>
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.MenuManage/HMI.MenuManage.csproj b/HMI.MenuManage/HMI.MenuManage.csproj
index bfdb3d1..e0e6184 100644
--- a/HMI.MenuManage/HMI.MenuManage.csproj
+++ b/HMI.MenuManage/HMI.MenuManage.csproj
@@ -62,8 +62,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
diff --git a/HMI.MenuManage/packages.config b/HMI.MenuManage/packages.config
index 6f57c8f..80bed4e 100644
--- a/HMI.MenuManage/packages.config
+++ b/HMI.MenuManage/packages.config
@@ -3,5 +3,5 @@
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.ParameterManage/HMI.ParameterManage.csproj b/HMI.ParameterManage/HMI.ParameterManage.csproj
index 65ac66f..de2e7cd 100644
--- a/HMI.ParameterManage/HMI.ParameterManage.csproj
+++ b/HMI.ParameterManage/HMI.ParameterManage.csproj
@@ -57,8 +57,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
diff --git a/HMI.ParameterManage/packages.config b/HMI.ParameterManage/packages.config
index 21b491c..c3ebe09 100644
--- a/HMI.ParameterManage/packages.config
+++ b/HMI.ParameterManage/packages.config
@@ -2,5 +2,5 @@
 <packages>
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.SettingControl/HMI.SettingControl.csproj b/HMI.SettingControl/HMI.SettingControl.csproj
index ad41524..8953547 100644
--- a/HMI.SettingControl/HMI.SettingControl.csproj
+++ b/HMI.SettingControl/HMI.SettingControl.csproj
@@ -56,8 +56,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
diff --git a/HMI.SettingControl/packages.config b/HMI.SettingControl/packages.config
index 21b491c..c3ebe09 100644
--- a/HMI.SettingControl/packages.config
+++ b/HMI.SettingControl/packages.config
@@ -2,5 +2,5 @@
 <packages>
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.UI/Converter/VisibilityBoolConverter.cs b/HMI.UI/Converter/VisibilityBoolConverter.cs
index 54c6626..8b92f73 100644
--- a/HMI.UI/Converter/VisibilityBoolConverter.cs
+++ b/HMI.UI/Converter/VisibilityBoolConverter.cs
@@ -18,7 +18,11 @@
 
         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
         {
-            return value;
+            if (value is Visibility flag && flag == Visibility.Visible)
+            {
+                return true;
+            }
+            return false;
         }
     }
 }
diff --git a/HMI.UI/Custom/NumberInput.cs b/HMI.UI/Custom/NumberInput.cs
new file mode 100644
index 0000000..d91c656
--- /dev/null
+++ b/HMI.UI/Custom/NumberInput.cs
@@ -0,0 +1,98 @@
+锘縰sing System.Text.RegularExpressions;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace HMI.UI
+{
+    public class NumberInput : TextBox
+    {
+        public NumberInput()
+        {
+            DataObject.AddPastingHandler(this, OnPasting);
+
+            // 绂佺敤杈撳叆娉�
+            InputMethod.SetIsInputMethodEnabled(this, false);
+
+            // 璁剧疆杈撳叆娉曟ā寮忎负瀛楁瘝
+            InputScope inputScope = new InputScope();
+            InputScopeName inputScopeName = new InputScopeName();
+            inputScopeName.NameValue = InputScopeNameValue.Number;
+            inputScope.Names.Add(inputScopeName);
+            this.InputScope = inputScope;
+        }
+
+        static NumberInput()
+        {
+            DefaultStyleKeyProperty.OverrideMetadata(typeof(NumberInput),
+                new FrameworkPropertyMetadata(typeof(NumberInput)));
+        }
+
+        public override void OnApplyTemplate()
+        {
+            base.OnApplyTemplate();
+        }
+
+        protected override void OnPreviewTextInput(TextCompositionEventArgs e)
+        {
+            // 鍏佽杈撳叆鏁板瓧銆佽礋鍙峰拰灏忔暟鐐�
+            Regex regex = new Regex(@"^-?\d*\.?\d*$");
+            string newText = this.Text.Insert(this.CaretIndex, e.Text);
+
+            // 妫�鏌ユ槸鍚﹀凡缁忔湁璐熷彿锛屽鏋滄湁鍒欎笉鍏佽鍐嶈緭鍏ヨ礋鍙�
+            if (e.Text == "-" && this.Text.Contains("-"))
+            {
+                e.Handled = true;
+                return;
+            }
+
+            // 妫�鏌ユ槸鍚﹀凡缁忔湁灏忔暟鐐癸紝濡傛灉鏈夊垯涓嶅厑璁稿啀杈撳叆灏忔暟鐐�
+            if (e.Text == "." && this.Text.Contains("."))
+            {
+                e.Handled = true;
+                return;
+            }
+
+            // 楠岃瘉瀹屾暣鐨勬柊鏂囨湰鏄惁绗﹀悎鏁板瓧鏍煎紡
+            if (!regex.IsMatch(newText))
+            {
+                e.Handled = true;
+                return;
+            }
+
+            base.OnPreviewTextInput(e);
+        }
+
+        protected override void OnPreviewKeyDown(KeyEventArgs e)
+        {
+            // 鍏佽浣跨敤閫�鏍奸敭鍜屽垹闄ら敭
+            if (e.Key == Key.Back || e.Key == Key.Delete)
+            {
+                base.OnPreviewKeyDown(e);
+                return;
+            }
+
+            // 鍏佽澶嶅埗绮樿创绛夊揩鎹烽敭
+            if (Keyboard.Modifiers == ModifierKeys.Control &&
+                (e.Key == Key.C || e.Key == Key.V || e.Key == Key.X))
+            {
+                base.OnPreviewKeyDown(e);
+                return;
+            }
+        }
+
+        private void OnPasting(object sender, DataObjectPastingEventArgs e)
+        {
+            if (e.DataObject.GetDataPresent(typeof(string)))
+            {
+                string text = (string)e.DataObject.GetData(typeof(string));
+                Regex regex = new Regex(@"^-?\d*\.?\d*$");
+
+                if (!regex.IsMatch(text))
+                {
+                    e.CancelCommand();
+                }
+            }
+        }
+    }
+}
diff --git a/HMI.UI/DpUtil/FormGroupHelper.cs b/HMI.UI/DpUtil/FormGroupHelper.cs
index e6ac850..01f6223 100644
--- a/HMI.UI/DpUtil/FormGroupHelper.cs
+++ b/HMI.UI/DpUtil/FormGroupHelper.cs
@@ -92,7 +92,7 @@
             if (content is ComboBox cBox) return cBox.SelectedItem ?? cBox.SelectedValue ?? cBox.Text;
 
             if (content is Panel panel) return GetValidateValue(panel.Children);
-            if (content is NumberInput numberInput) return numberInput.Value;
+            if (content is Panuon.WPF.UI.NumberInput numberInput) return numberInput.Value;
             if (content is PasswordBox passwordInput) return passwordInput.Password;
             return null;
         }
diff --git a/HMI.UI/HMI.UI.csproj b/HMI.UI/HMI.UI.csproj
index 3255fc9..0034e0a 100644
--- a/HMI.UI/HMI.UI.csproj
+++ b/HMI.UI/HMI.UI.csproj
@@ -61,8 +61,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Data" />
@@ -84,6 +84,7 @@
     <Compile Include="Converter\DataGridRowFlagConverter.cs" />
     <Compile Include="Converter\DataGridRowNumberConverter.cs" />
     <Compile Include="Converter\PathImageConverter.cs" />
+    <Compile Include="Custom\NumberInput.cs" />
     <Compile Include="DpUtil\DataGridHelper.cs" />
     <Compile Include="DpUtil\DataGridTextColumnHelper.cs" />
     <Compile Include="DpUtil\FormGroupHelper.cs" />
diff --git a/HMI.UI/Style/FormStyle.xaml b/HMI.UI/Style/FormStyle.xaml
index 1cd04c2..3bda03a 100644
--- a/HMI.UI/Style/FormStyle.xaml
+++ b/HMI.UI/Style/FormStyle.xaml
@@ -106,7 +106,7 @@
     <Style x:Key="InputFormGroupStyle" TargetType="pu:FormGroup">
         <Style.Resources>
             <Style TargetType="TextBox" BasedOn="{StaticResource EditorTextBoxStyle}">
-                
+
             </Style>
         </Style.Resources>
         <Setter Property="HeaderWidth" Value="Auto" />
diff --git a/HMI.UI/Style/MsgBoxStyle.xaml b/HMI.UI/Style/MsgBoxStyle.xaml
index a29c393..1858f41 100644
--- a/HMI.UI/Style/MsgBoxStyle.xaml
+++ b/HMI.UI/Style/MsgBoxStyle.xaml
@@ -13,6 +13,7 @@
                 <Setter Property="pu:WindowXCaption.Foreground" Value="{StaticResource WarningColorContract}" />
                 <Setter Property="Width" Value="350" />
                 <Setter Property="Height" Value="200" />
+                <Setter Property="SizeToContent" Value="Manual" />
             </Style>
         </pu:MessageBoxXSettings.WindowXStyle>
 
@@ -51,6 +52,7 @@
                 <Setter Property="pu:WindowXCaption.Foreground" Value="{StaticResource DangerColorContrast}" />
                 <Setter Property="Width" Value="350" />
                 <Setter Property="Height" Value="200" />
+                <Setter Property="SizeToContent" Value="Manual" />
             </Style>
         </pu:MessageBoxXSettings.WindowXStyle>
 
@@ -89,6 +91,7 @@
                 <Setter Property="pu:WindowXCaption.Foreground" Value="{StaticResource PrimaryColorContract}" />
                 <Setter Property="Width" Value="350" />
                 <Setter Property="Height" Value="200" />
+                <Setter Property="SizeToContent" Value="Manual" />
             </Style>
         </pu:MessageBoxXSettings.WindowXStyle>
 
diff --git a/HMI.UI/Style/PanuonResource.xaml b/HMI.UI/Style/PanuonResource.xaml
index 3d29dc3..0b103f5 100644
--- a/HMI.UI/Style/PanuonResource.xaml
+++ b/HMI.UI/Style/PanuonResource.xaml
@@ -155,7 +155,7 @@
     <Style x:Key="CardBoarder" TargetType="Border">
         <Setter Property="BorderBrush" Value="{StaticResource CommonBoarder}"/>
         <Setter Property="BorderThickness" Value="2"/>
-        <Setter Property="Background" Value="#FFF"/>
+        <Setter Property="Background" Value="#f3f9ff"/>
         <Setter Property="Margin" Value="10"/>
         <Setter Property="Padding" Value="10"/>
     </Style>
diff --git a/HMI.UI/packages.config b/HMI.UI/packages.config
index 18db34a..66e7efd 100644
--- a/HMI.UI/packages.config
+++ b/HMI.UI/packages.config
@@ -1,5 +1,5 @@
 锘�<?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/HMI.UnitTest/HMI.UnitTest.csproj b/HMI.UnitTest/HMI.UnitTest.csproj
index cd246aa..d4cc6cd 100644
--- a/HMI.UnitTest/HMI.UnitTest.csproj
+++ b/HMI.UnitTest/HMI.UnitTest.csproj
@@ -61,8 +61,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
diff --git a/HMI.UnitTest/packages.config b/HMI.UnitTest/packages.config
index 21b491c..c3ebe09 100644
--- a/HMI.UnitTest/packages.config
+++ b/HMI.UnitTest/packages.config
@@ -2,5 +2,5 @@
 <packages>
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/Libs/OpcInterface.dll b/Libs/OpcInterface.dll
deleted file mode 100644
index 67ba8ec..0000000
--- a/Libs/OpcInterface.dll
+++ /dev/null
Binary files differ
diff --git a/Plugin.DOControl/DOControl.xaml b/Plugin.DOControl/DOControl.xaml
new file mode 100644
index 0000000..30bfef1
--- /dev/null
+++ b/Plugin.DOControl/DOControl.xaml
@@ -0,0 +1,112 @@
+锘�<hb:PluginControl x:Class="HMI.DOControl.DOControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+             xmlns:local="clr-namespace:HMI.DOControl"
+             xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+             xmlns:pw="https://opensource.panuon.com/wpf"
+             xmlns:pu="https://opensource.panuon.com/wpf-ui"
+             xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+             mc:Ignorable="d"
+             Loaded="UserControl_Loaded"
+             Background="{StaticResource WorkspaceBackground}"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <Border Style="{StaticResource CardBoarder}">
+
+
+        <Grid dp:GridHelper.Space="10" Cursor="">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="Auto"/>
+                <RowDefinition Height="Auto"/>
+                <RowDefinition/>
+            </Grid.RowDefinitions>
+
+            <TextBlock FontSize="{StaticResource TitleFontSize}" 
+VerticalAlignment="Center" HorizontalAlignment="Left" Text="鏃ュ織鏌ヨ"/>
+
+            <DockPanel Grid.Row="1" Cursor="">
+                <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
+                    <Button Style="{StaticResource QueryBtn}"
+                            x:Name="queryBtn" Click="Button_Click"/>
+                    <Button Style="{StaticResource RfhBtn}"
+                            x:Name="resetBtn" Click="Button_Click"/>
+                    <Button x:Name="exportBtn"
+                            Style="{StaticResource ExportBtn}" Click="Button_Click"/>
+                </StackPanel>
+
+                <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Left">
+                    <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="绾у埆"/>
+                    <ComboBox Style="{StaticResource FormComboxStyle}" x:Name="levelInput" 
+                              Width="180"
+                              SelectedValuePath="Content">
+                        <ComboBoxItem Content="info"/>
+                        <ComboBoxItem Content="warn"/>
+                        <ComboBoxItem Content="error"/>
+                    </ComboBox>
+
+                    <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="寮�濮嬫椂闂�"/>
+                    <pu:DateTimePicker Style="{StaticResource TimePicker}" x:Name="startTimeInput"/>
+
+                    <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="缁撴潫鏃堕棿"/>
+                    <pu:DateTimePicker Style="{StaticResource TimePicker}" x:Name="endTimeInput"/>
+
+                    <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="鏉ユ簮"/>
+                    <!--<ComboBox Style="{StaticResource FormComboxStyle}" x:Name="sourceInput" Width="180"></ComboBox>-->
+                    <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="sourceInput" Width="180"/>
+
+                    <TextBlock Style="{StaticResource TitleBox}" FontSize="14" Text="瀹炴椂鍒锋柊"/>
+                    <CheckBox x:Name="autoRfhInput" HorizontalAlignment="Center" VerticalAlignment="Center"
+                              IsChecked="{Binding AutoRfh,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+                              />
+                </StackPanel>
+            </DockPanel>
+
+
+            <DataGrid Grid.Row="2" x:Name="table" Style="{StaticResource DefaultDataGrid}">
+                <DataGrid.RowStyle>
+                    <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Static pu:StyleKeys.DataGridRowStyle}}">
+                        <Style.Triggers>
+                            <DataTrigger Binding="{Binding type}" Value="warn">
+                                <Setter Property="Background" Value="{StaticResource WarningColor}"/>
+                                <Setter Property="Foreground" Value="Black"/>
+                            </DataTrigger>
+                            <DataTrigger Binding="{Binding type}" Value="error">
+                                <Setter Property="Background" Value="{StaticResource DangerColor}"/>
+                                <Setter Property="Foreground" Value="Black"/>
+                            </DataTrigger>
+                            <Trigger Property="IsSelected" Value="True">
+                                <Setter Property="Background" Value="Transparent"/>
+                            </Trigger>
+                            <Trigger Property="IsMouseOver" Value="True">
+                                <Setter Property="Background" Value="Transparent"/>
+                            </Trigger>
+                        </Style.Triggers>
+                    </Style>
+                </DataGrid.RowStyle>
+                <DataGrid.Columns>
+                    <DataGridTemplateColumn Header="" Width="Auto" CanUserResize="False">
+                        <DataGridTemplateColumn.CellTemplate>
+                            <DataTemplate>
+                                <CheckBox VerticalAlignment="Center" IsChecked="{Binding Selected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
+                            </DataTemplate>
+                        </DataGridTemplateColumn.CellTemplate>
+                    </DataGridTemplateColumn>
+                    <DataGridTemplateColumn Header="#" CanUserResize="False">
+                        <DataGridTemplateColumn.CellTemplate>
+                            <DataTemplate>
+                                <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+    RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+                            </DataTemplate>
+                        </DataGridTemplateColumn.CellTemplate>
+                    </DataGridTemplateColumn>
+                    <DataGridTextColumn Width="*" Binding="{Binding type}" Header="绾у埆" />
+                    <DataGridTextColumn Width="*" Binding="{Binding time}" Header="鏃堕棿" />
+                    <DataGridTextColumn Width="*" Binding="{Binding source}" Header="鏉ユ簮" />
+                    <DataGridTextColumn Width="*" Binding="{Binding text}" Header="鏂囨湰" />
+                </DataGrid.Columns>
+            </DataGrid>
+        </Grid>
+    </Border>
+</hb:PluginControl>
\ No newline at end of file
diff --git a/Plugin.DOControl/DOControl.xaml.cs b/Plugin.DOControl/DOControl.xaml.cs
new file mode 100644
index 0000000..e6e4aa3
--- /dev/null
+++ b/Plugin.DOControl/DOControl.xaml.cs
@@ -0,0 +1,46 @@
+锘縰sing HMI.Base;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace HMI.DOControl
+{
+    /// <summary>
+    /// UserControl1.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class DOControl : PluginControl
+    {
+        public DOControl()
+        {
+            InitializeComponent();
+        }
+
+        public override void InitFinish()
+        {
+            base.InitFinish();
+            
+        }
+
+
+        private void UserControl_Loaded(object sender, RoutedEventArgs e)
+        {
+            
+            Loaded -= UserControl_Loaded;
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+            Button btn = sender as Button;
+            switch (btn.Name)
+            {
+                case "queryBtn":
+                    break;
+                case "resetBtn":
+                    break;
+                case "exportBtn":
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/Plugin.DOControl/Plugin.DOControl.csproj b/Plugin.DOControl/Plugin.DOControl.csproj
new file mode 100644
index 0000000..fb506b7
--- /dev/null
+++ b/Plugin.DOControl/Plugin.DOControl.csproj
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{306A83DC-A7DB-4057-BAA7-477D8756F5D9}</ProjectGuid>
+    <OutputType>library</OutputType>
+    <RootNamespace>Plugin.DOControl</RootNamespace>
+    <AssemblyName>Plugin.DOControl</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
+    </Reference>
+    <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
+    </Reference>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+  </ItemGroup>
+  <ItemGroup>
+    <Page Include="DOControl.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="DOControl.xaml.cs">
+      <DependentUpon>DOControl.xaml</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="packages.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HMI.Base\HMI.Base.csproj">
+      <Project>{2a6f9720-a890-4036-9d73-41a0dae28341}</Project>
+      <Name>HMI.Base</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HMI.Core\HMI.Core.csproj">
+      <Project>{3e3bf44a-0b69-45c5-9512-528cb48a7106}</Project>
+      <Name>HMI.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HMI.UI\HMI.UI.csproj">
+      <Project>{f17de6b5-af1d-48c6-94a0-6b763a6546a6}</Project>
+      <Name>HMI.UI</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HMI.Util\HMI.Util.csproj">
+      <Project>{afea100a-9223-448d-ab10-3015d93dd98c}</Project>
+      <Name>HMI.Util</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/Plugin.DOControl/Properties/AssemblyInfo.cs b/Plugin.DOControl/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9ed5aac
--- /dev/null
+++ b/Plugin.DOControl/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+锘縰sing System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("Plugin.DOControl")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Plugin.DOControl")]
+[assembly: AssemblyCopyright("Copyright 漏  2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+//鑻ヨ寮�濮嬬敓鎴愬彲鏈湴鍖栫殑搴旂敤绋嬪簭锛岃璁剧疆
+//.csproj 鏂囦欢涓殑 <UICulture>CultureYouAreCodingWith</UICulture>
+//鍦� <PropertyGroup> 涓�備緥濡傦紝濡傛灉浣犱娇鐢ㄧ殑鏄編鍥借嫳璇��
+//浣跨敤鐨勬槸缇庡浗鑻辫锛岃灏� <UICulture> 璁剧疆涓� en-US銆�  鐒跺悗鍙栨秷
+//瀵逛互涓� NeutralResourceLanguage 鐗规�х殑娉ㄩ噴銆�  鏇存柊
+//浠ヤ笅琛屼腑鐨勨�渆n-US鈥濅互鍖归厤椤圭洰鏂囦欢涓殑 UICulture 璁剧疆銆�
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly:ThemeInfo(
+    ResourceDictionaryLocation.None, //涓婚鐗瑰畾璧勬簮璇嶅吀鎵�澶勪綅缃�
+                             //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+                             //鎴栧簲鐢ㄧ▼搴忚祫婧愬瓧鍏镐腑鎵惧埌鏃朵娇鐢�)
+    ResourceDictionaryLocation.SourceAssembly //甯歌璧勬簮璇嶅吀鎵�澶勪綅缃�
+                                      //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+                                      //銆佸簲鐢ㄧ▼搴忔垨浠讳綍涓婚涓撶敤璧勬簮瀛楀吀涓壘鍒版椂浣跨敤)
+)]
+
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�: 
+//
+//      涓荤増鏈�
+//      娆$増鏈�
+//      鐢熸垚鍙�
+//      淇鍙�
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Plugin.DOControl/Properties/Resources.Designer.cs b/Plugin.DOControl/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..cb98792
--- /dev/null
+++ b/Plugin.DOControl/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+锘�//------------------------------------------------------------------------------
+// <auto-generated>
+//     姝や唬鐮佺敱宸ュ叿鐢熸垚銆�
+//     杩愯鏃剁増鏈�: 4.0.30319.42000
+//
+//     瀵规鏂囦欢鐨勬洿鏀瑰彲鑳藉鑷翠笉姝g‘鐨勮涓猴紝濡傛灉
+//     閲嶆柊鐢熸垚浠g爜锛屽垯鎵�鍋氭洿鏀瑰皢涓㈠け銆�
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Plugin.DOControl.Properties {
+    
+    
+    /// <summary>
+    ///   寮虹被鍨嬭祫婧愮被锛岀敤浜庢煡鎵炬湰鍦板寲瀛楃涓茬瓑銆�
+    /// </summary>
+    // 姝ょ被鏄敱 StronglyTypedResourceBuilder
+    // 绫婚�氳繃绫讳技浜� ResGen 鎴� Visual Studio 鐨勫伐鍏疯嚜鍔ㄧ敓鎴愮殑銆�
+    // 鑻ヨ娣诲姞鎴栫Щ闄ゆ垚鍛橈紝璇风紪杈� .ResX 鏂囦欢锛岀劧鍚庨噸鏂拌繍琛� ResGen
+    // (浠� /str 浣滀负鍛戒护閫夐」)锛屾垨閲嶆柊鐢熸垚 VS 椤圭洰銆�
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   杩斿洖姝ょ被浣跨敤鐨勭紦瀛� ResourceManager 瀹炰緥銆�
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if ((resourceMan == null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Plugin.DOControl.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   閲嶅啓褰撳墠绾跨▼鐨� CurrentUICulture 灞炴�э紝瀵�
+        ///   浣跨敤姝ゅ己绫诲瀷璧勬簮绫荤殑鎵�鏈夎祫婧愭煡鎵炬墽琛岄噸鍐欍��
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
diff --git a/Plugin.DOControl/Properties/Resources.resx b/Plugin.DOControl/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/Plugin.DOControl/Properties/Resources.resx
@@ -0,0 +1,117 @@
+锘�<?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.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: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" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </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" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/Plugin.DOControl/Properties/Settings.Designer.cs b/Plugin.DOControl/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..3a8d07b
--- /dev/null
+++ b/Plugin.DOControl/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+锘�//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Plugin.DOControl.Properties
+{
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}
diff --git a/Plugin.DOControl/Properties/Settings.settings b/Plugin.DOControl/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/Plugin.DOControl/Properties/Settings.settings
@@ -0,0 +1,7 @@
+锘�<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
\ No newline at end of file
diff --git a/Plugin.DOControl/packages.config b/Plugin.DOControl/packages.config
new file mode 100644
index 0000000..c3ebe09
--- /dev/null
+++ b/Plugin.DOControl/packages.config
@@ -0,0 +1,6 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="log4net" version="3.0.4" targetFramework="net472" />
+  <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
+</packages>
\ No newline at end of file
diff --git a/Plugin.ServoManage/Entity/ServoData.cs b/Plugin.ServoManage/Entity/ServoData.cs
new file mode 100644
index 0000000..a9b4834
--- /dev/null
+++ b/Plugin.ServoManage/Entity/ServoData.cs
@@ -0,0 +1,15 @@
+锘縰sing HMI.Core.Entity;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Plugin.ServoManage.Entity
+{
+    public class ServoData :SelectBase
+    {
+        public string Name { get; set; }
+        public string Unit { get; set; }
+    }
+}
diff --git a/Plugin.ServoManage/Entity/ServoProductData.cs b/Plugin.ServoManage/Entity/ServoProductData.cs
new file mode 100644
index 0000000..2505f3e
--- /dev/null
+++ b/Plugin.ServoManage/Entity/ServoProductData.cs
@@ -0,0 +1,14 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Plugin.ServoManage.Entity
+{
+    public class ServoProductData
+    {
+        public string Model { get; set; }
+        public string ProgramCode { get; set; }
+    }
+}
diff --git a/Plugin.ServoManage/NumberPanel.xaml b/Plugin.ServoManage/NumberPanel.xaml
new file mode 100644
index 0000000..f7a6548
--- /dev/null
+++ b/Plugin.ServoManage/NumberPanel.xaml
@@ -0,0 +1,78 @@
+锘�<pu:WindowX x:Class="Plugin.ServoManage.NumberPanel"
+            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+            xmlns:local="clr-namespace:Plugin.ServoManage"
+            xmlns:pw="https://opensource.panuon.com/wpf"
+            xmlns:pu="https://opensource.panuon.com/wpf-ui"
+            xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+            xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+            xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+            mc:Ignorable="d"
+            Title="Form"
+            SizeToContent="Height"
+            Width="500"
+            FontSize="14"
+            FontWeight="Bold"
+            WindowStartupLocation="CenterOwner"
+            pu:WindowXModalDialog.Buttons="{x:Null}"
+            Style="{StaticResource ModalWindow}">
+    <Window.Resources>
+        <Style TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
+            <Setter Property="Padding" Value="16"/>
+        </Style>
+    </Window.Resources>
+    
+    <Grid dp:GridHelper.Space="10" Margin="10">
+        <Grid.RowDefinitions>
+            <RowDefinition/>
+            <RowDefinition/>
+            <RowDefinition/>
+            <RowDefinition/>
+            <RowDefinition/>
+            <RowDefinition/>
+        </Grid.RowDefinitions>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition/>
+            <ColumnDefinition/>
+            <ColumnDefinition/>
+            <ColumnDefinition/>
+        </Grid.ColumnDefinitions>
+
+        <ui:NumberInput Grid.ColumnSpan="4" BorderThickness="1"
+                        BorderBrush="Black"
+                        Style="{StaticResource EditorTextBoxStyle}"
+                        x:Name="NiNumber"/>
+        
+        <!--<Button Grid.Row="1" Tag="LeftArrow" Click="Button_Click" Content="猬�"/>
+        <Button Grid.Row="1" Grid.Column="1"
+                Tag="RightArrow"
+                Click="Button_Click"
+                Content="zuojiantou"/>-->
+
+
+        <Button Grid.Row="1" Tag="ESC" Click="Button_Click" Content="ESC"/>
+        <Button Grid.Row="1" Grid.Column="1" Tag="-" Click="Button_Click" Content="-"/>
+
+        <Button Grid.Row="1" Grid.Column="2" Tag="AC" Click="Button_Click" Content="AC"/>
+        <Button Grid.Row="1" Grid.Column="3" Tag="Backspace" Click="Button_Click" Content="Del"/>
+
+        <Button Grid.Row="2" Tag="7" Click="Button_Click" Content="7"/>
+        <Button Grid.Row="2" Grid.Column="1" Tag="8" Click="Button_Click" Content="8"/>
+        <Button Grid.Row="2" Grid.Column="2" Tag="9" Click="Button_Click" Content="9"/>
+        <Button Grid.Row="2" Grid.RowSpan="4" Tag="Enter" Click="Button_Click" Grid.Column="3" Content="Enter"/>
+
+
+        <Button Grid.Row="3" Tag="4" Click="Button_Click" Content="4"/>
+        <Button Grid.Row="3" Grid.Column="1" Tag="5" Click="Button_Click" Content="5"/>
+        <Button Grid.Row="3" Grid.Column="2" Tag="6" Click="Button_Click" Content="6"/>
+ 
+        <Button Grid.Row="4" Tag="1" Click="Button_Click" Content="1"/>
+        <Button Grid.Row="4" Grid.Column="1" Tag="2" Click="Button_Click" Content="2"/>
+        <Button Grid.Row="4" Grid.Column="2" Tag="3" Click="Button_Click" Content="3"/>
+
+        <Button Grid.Row="5" Grid.ColumnSpan="2" Tag="0" Click="Button_Click" Content="0"/>
+        <Button Grid.Row="5" Grid.Column="2" Tag="." Click="Button_Click" Content="."/>
+    </Grid>
+</pu:WindowX>
diff --git a/Plugin.ServoManage/NumberPanel.xaml.cs b/Plugin.ServoManage/NumberPanel.xaml.cs
new file mode 100644
index 0000000..4391274
--- /dev/null
+++ b/Plugin.ServoManage/NumberPanel.xaml.cs
@@ -0,0 +1,160 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.DpUtil;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using Plugin.ServoManage.Entity;
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Windows.Controls;
+
+namespace Plugin.ServoManage
+{
+    /// <summary>
+    /// ModalWindow.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class NumberPanel : WindowX
+    {
+        public NumberPanel()
+        {
+            this.DataContext = this;
+            InitializeComponent();
+        }
+
+        public double? Data { get; private set; }
+
+        private bool _isProcessing;
+
+        protected override void OnClosing(CancelEventArgs e)
+        {
+            //Press Continue Button
+            if (DialogResult == true)
+            {
+                if (_isProcessing)
+                {
+                    e.Cancel = true;
+                    return;
+                }
+                try
+                {
+
+                }
+                catch (Exception ex)
+                {
+
+                    return;
+                }
+                finally
+                {
+                    _isProcessing = false;
+                }
+            }
+            base.OnClosing(e);
+        }
+
+        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
+        {
+            Button btn = sender as Button;
+            switch (btn.Tag.ToString())
+            {
+                case "LeftArrow":
+                    break;
+                case "RightArrow":
+                    break;
+                case "AC":
+                    NiNumber.Text = null;
+                    break;
+                case "Backspace":
+                    HandleBackspace();
+                    break;
+                case "Enter":
+                    DialogResult = true;
+                    Data = double.Parse(NiNumber.Text);
+                    this.Close();
+                    break;
+                case "ESC":
+                    DialogResult = false;
+                    this.Close();
+                    break;
+                case "-":
+                    var str = NiNumber.Text;
+                    if (string.IsNullOrEmpty(str))
+                    {
+                        NiNumber.Text = "-";
+                    }
+                    else if (str.StartsWith("-"))
+                    {
+                        NiNumber.Text = str.Replace("-", "");
+                    }
+                    else
+                    {
+                        NiNumber.Text = "-" + str;
+                    }
+                    break;
+                case ".":
+                    HandleDot();
+                    break;
+                default:
+                    HandleNumberInput(btn.Tag.ToString());
+                    break;
+            }
+        }
+
+        private void HandleBackspace()
+        {
+            var str = NiNumber.Text?.ToString();
+            if (string.IsNullOrEmpty(str))
+            {
+                return;
+            }
+            else
+            {
+                NiNumber.Text = str.Substring(0, str.Length - 1);
+            }
+        }
+
+        private void HandleDot()
+        {
+            var str = NiNumber.Text?.ToString();
+            if (string.IsNullOrEmpty(str) || str.IndexOf(".") > 0)
+            {
+                return;
+            }
+            else
+            {
+                NiNumber.Text = str + ".";
+            }
+        }
+
+        public bool? Open(string dataStr)
+        {
+            try
+            {
+                Data = double.Parse(dataStr);
+                NiNumber.Text = dataStr;
+            }
+            catch (Exception ex)
+            {
+                Data = null;
+                NiNumber.Text = null;
+            }
+            return this.ShowDialog();
+        }
+
+        private void HandleNumberInput(string numStr)
+        {
+            var str = NiNumber.Text?.ToString();
+            if (string.IsNullOrEmpty(str))
+            {
+                NiNumber.Text = numStr;
+            }
+            else
+            {
+                NiNumber.Text = str + numStr;
+            }
+        }
+
+    }
+}
diff --git a/Plugin.ServoManage/Plugin.ServoManage.csproj b/Plugin.ServoManage/Plugin.ServoManage.csproj
index 2bbb589..e8a5aa1 100644
--- a/Plugin.ServoManage/Plugin.ServoManage.csproj
+++ b/Plugin.ServoManage/Plugin.ServoManage.csproj
@@ -56,8 +56,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />
@@ -77,6 +77,20 @@
     <Reference Include="PresentationFramework" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Entity\ServoData.cs" />
+    <Compile Include="Entity\ServoProductData.cs" />
+    <Compile Include="NumberPanel.xaml.cs">
+      <DependentUpon>NumberPanel.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="ServoProductModal.xaml.cs">
+      <DependentUpon>ServoProductModal.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="ServoModal.xaml.cs">
+      <DependentUpon>ServoModal.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="ServoSetting.xaml.cs">
+      <DependentUpon>ServoSetting.xaml</DependentUpon>
+    </Compile>
     <Page Include="ServoManage.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
@@ -85,6 +99,22 @@
       <DependentUpon>ServoManage.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
+    <Page Include="NumberPanel.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="ServoProductModal.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="ServoModal.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="ServoSetting.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs">
@@ -111,6 +141,10 @@
     </None>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\HMI.Old\OPCInterface\OpcInterface\OpcInterface.csproj">
+      <Project>{e1464149-2c0a-499d-ab90-0c72e6ed1c53}</Project>
+      <Name>OpcInterface</Name>
+    </ProjectReference>
     <ProjectReference Include="..\HMI.Base\HMI.Base.csproj">
       <Project>{2a6f9720-a890-4036-9d73-41a0dae28341}</Project>
       <Name>HMI.Base</Name>
@@ -119,10 +153,17 @@
       <Project>{3e3bf44a-0b69-45c5-9512-528cb48a7106}</Project>
       <Name>HMI.Core</Name>
     </ProjectReference>
+    <ProjectReference Include="..\HMI.ParameterManage\HMI.ParameterManage.csproj">
+      <Project>{736cd77d-b81e-4866-bb00-84b0b57110f0}</Project>
+      <Name>HMI.ParameterManage</Name>
+    </ProjectReference>
     <ProjectReference Include="..\HMI.UI\HMI.UI.csproj">
       <Project>{f17de6b5-af1d-48c6-94a0-6b763a6546a6}</Project>
       <Name>HMI.UI</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <WCFMetadata Include="Connected Services\" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>
\ No newline at end of file
diff --git a/Plugin.ServoManage/ServoManage.xaml b/Plugin.ServoManage/ServoManage.xaml
index 421d871..e1976c8 100644
--- a/Plugin.ServoManage/ServoManage.xaml
+++ b/Plugin.ServoManage/ServoManage.xaml
@@ -1,4 +1,4 @@
-锘�<UserControl x:Class="Plugin.ServoManage.ServoManage"
+锘�<hb:PluginControl x:Class="Plugin.ServoManage.ServoManage"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
@@ -14,17 +14,40 @@
              Loaded="UserControl_Loaded"
              d:DesignHeight="450" d:DesignWidth="800">
     <UserControl.Resources>
+        <Style x:Key="PrimaryButton" TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
+            <Setter Property="Padding" Value="15"/>
+        </Style>
+
+        <Style x:Key="LightBall" TargetType="Ellipse">
+            <Setter Property="Height" Value="35"/>
+            <Setter Property="Width" Value="35"/>
+            <Setter Property="Fill" Value="{StaticResource Normal}"/>
+            <Setter Property="Margin" Value="0,10,0,0"/>
+            <Style.Triggers>
+                <DataTrigger Binding="{Binding }" Value="1">
+                    <Setter Property="Fill" Value="{StaticResource Ok}"/>
+                </DataTrigger>
+            </Style.Triggers>
+        </Style>
+
         <Style x:Key="Desc" TargetType="Label">
-            <Setter Property="Padding" Value="10"/>
-            <Setter Property="FontSize" Value="12"/>
+            <Setter Property="Padding" Value="10,15"/>
+            <Setter Property="MinWidth" Value="90"/>
+            <Setter Property="FontSize" Value="14"/>
             <Setter Property="BorderThickness" Value="1"/>
             <Setter Property="BorderBrush" Value="#3a3a3a"/>
             <Setter Property="HorizontalContentAlignment" Value="Center"/>
             <Setter Property="VerticalContentAlignment" Value="Center"/>
         </Style>
 
+        <Style x:Key="ReadLabel" TargetType="Label" BasedOn="{StaticResource Desc}">
+            <Setter Property="BorderThickness" Value="1,0,1,1"/>
+            <Setter Property="Background" Value="LightGray"/>
+        </Style>
+
         <Style x:Key="LabelText" TargetType="Label" BasedOn="{StaticResource Desc}">
             <Setter Property="BorderThickness" Value="1,0,1,1"/>
+            <Setter Property="Cursor" Value="Hand"/>
         </Style>
 
         <Style x:Key="BDesc" TargetType="Label" BasedOn="{StaticResource Desc}">
@@ -34,8 +57,12 @@
         <Style x:Key="YDesc" TargetType="Label" BasedOn="{StaticResource Desc}">
             <Setter Property="Background" Value="#ffff00"/>
         </Style>
+
+        <Style TargetType="GroupBox">
+            <Setter Property="Padding" Value="5"/>
+        </Style>
     </UserControl.Resources>
-    
+
     <Border Style="{StaticResource CardBoarder}">
         <Grid dp:GridHelper.Space="10">
             <Grid.RowDefinitions>
@@ -51,10 +78,8 @@
 
             <DockPanel Grid.ColumnSpan="2">
                 <StackPanel DockPanel.Dock="Right" Style="{StaticResource ButtonGroup}">
-                    <Button Style="{StaticResource AddBtn}" x:Name="addBtn" Click="Button_Click"/>
-                    <Button Style="{StaticResource EditBtn}" x:Name="editBtn" Click="Button_Click"/>
-                    <Button Style="{StaticResource RfhBtn}" x:Name="rfhBtn" Click="Button_Click"/>
-                    <Button Style="{StaticResource DelBtn}" x:Name="delBtn" Click="Button_Click"/>
+                    <Button Style="{StaticResource AddBtn}" x:Name="addServoBtn" Click="Button_Click"/>
+                    <Button Style="{StaticResource RfhBtn}" x:Name="rfhServoBtn" Click="Button_Click"/>
                 </StackPanel>
                 <TextBlock Style="{StaticResource TitleBox}" Text="{DynamicResource svo.title}"/>
             </DockPanel>
@@ -102,9 +127,6 @@
                                                         </Setter.Value>
                                                     </Setter>
                                                 </DataTrigger>
-                                                <Trigger Property="IsChecked" Value="True">
-                                                    <Setter Property="Background" Value="Red"/>
-                                                </Trigger>
                                             </Style.Triggers>
                                         </Style>
                                     </ToggleButton.Style>
@@ -131,7 +153,8 @@
                                       IsReadOnly="False"
                                       SelectionMode="Single"
                                       BorderThickness="0"
-                                      ItemsSource="{Binding Datas}">
+                                      SelectedItem="{Binding SelectedServo}"
+                                      ItemsSource="{Binding Servos}">
                                 <DataGrid.Columns>
                                     <DataGridTemplateColumn Header="#" IsReadOnly="True" CanUserResize="False">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -166,7 +189,6 @@
                                         </DataGridTemplateColumn.CellTemplate>
                                     </DataGridTemplateColumn>
                                 </DataGrid.Columns>
-
                             </DataGrid>
                         </Grid>
 
@@ -203,136 +225,37 @@
                         </Grid.RowDefinitions>
 
                         <DockPanel>
-                            <StackPanel Style="{StaticResource ButtonGroup}">
-                                <TextBlock Style="{StaticResource TitleBox}" 
+                            <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Left">
+                                <!--<TextBlock Style="{StaticResource TitleBox}" 
                                            FontSize="{StaticResource ContentFontSize2}" 
-                                           Text="{DynamicResource svo.product}"/>
-                                <ComboBox x:Name="productInput" Style="{StaticResource FormComboxStyle}" MinWidth="180" />
+                                           Text="{DynamicResource svo.product.model}"/>
+                                <ComboBox x:Name="productInput" 
+                                          IsEnabled="{Binding HasSelectedServo}"
+                                          SelectedItem="{Binding SelectedProduct}"
+                                          ItemsSource="{Binding ServoProducts}"
+                                          DisplayMemberPath="Model"
+                                          Style="{StaticResource FormComboxStyle}" MinWidth="180" />
 
-                                <Button Style="{StaticResource AddBtn}" Click="Button_Click"/>
-                                <Button Style="{StaticResource EditBtn}" Click="Button_Click"/>
-                                <Button Style="{StaticResource RfhBtn}" Click="Button_Click"/>
-                                <Button Style="{StaticResource DelBtn}" Click="Button_Click"/>
+                                <Button Style="{StaticResource AddBtn}" x:Name="addProductBtn" Click="Button_Click"/>
+                                <Button Style="{StaticResource EditBtn}" x:Name="editProductBtn" Click="Button_Click"/>
+                                <Button Style="{StaticResource RfhBtn}" x:Name="rfhProductBtn" Click="Button_Click"/>
+                                <Button Style="{StaticResource DelBtn}" x:Name="delProductBtn" Click="Button_Click"/>-->
                             </StackPanel>
                         </DockPanel>
 
-                        <WrapPanel Grid.Row="1">
-                            <GroupBox Header="鎶ヨ" Padding="10">
-                                <StackPanel Style="{StaticResource ButtonGroup}">
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="鎺у埗鎶ヨ"/>
-                                        <Label Style="{StaticResource LabelText}" Content="鎺у埗鎶ヨ"/>
-                                    </StackPanel>
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="椹卞姩鎶ヨ"/>
-                                        <Label Style="{StaticResource LabelText}" Content="鎺у埗鎶ヨ"/>
-                                    </StackPanel>
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="鏁呴殰椹卞姩"/>
-                                        <Label Style="{StaticResource LabelText}" Content="0"/>
-                                    </StackPanel>
-                                </StackPanel>
-                            </GroupBox>
+                        <Grid Grid.Row="1" dp:GridHelper.Space="10">
+                            <Grid.RowDefinitions>
+                                <RowDefinition Height="Auto"/>
+                                <RowDefinition/>
+                            </Grid.RowDefinitions>
 
-                            <GroupBox Header="浣嶇疆" Padding="10">
-                                <StackPanel Style="{StaticResource ButtonGroup}">
-                                    <StackPanel>
-                                        <Label Style="{StaticResource BDesc}" Content="褰撳墠浣嶇疆"/>
-                                        <Label Style="{StaticResource LabelText}" Content="0"/>
-                                    </StackPanel>
+                            <Grid.ColumnDefinitions>
+                                <ColumnDefinition Width="Auto"/>
+                                <ColumnDefinition Width="Auto"/>
+                                <ColumnDefinition Width="Auto"/>
+                            </Grid.ColumnDefinitions>
 
-                                    <StackPanel>
-                                        <Label Style="{StaticResource BDesc}" Content="褰撳墠閫熷害"/>
-                                        <Label Style="{StaticResource LabelText}" Content="0"/>
-                                    </StackPanel>
-                                    <StackPanel>
-                                        <Label Style="{StaticResource BDesc}" Content="鍔犻�熷害"/>
-                                        <Label Style="{StaticResource LabelText}" Content="0"/>
-                                    </StackPanel>
-                                    <StackPanel>
-                                        <Label Style="{StaticResource BDesc}" Content="鍑忛�熷害"/>
-                                        <Label Style="{StaticResource LabelText}" Content="0"/>
-                                    </StackPanel>
-                                </StackPanel>
-                            </GroupBox>
-
-                            <GroupBox Header="鐘舵��" Padding="10">
-                                <StackPanel Style="{StaticResource ButtonGroup}">
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="浣胯兘"/>
-                                        <Label Style="{StaticResource LabelText}">
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="鍑嗗濂�"/>
-                                        <Label Style="{StaticResource LabelText}">
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="杩愯涓�"/>
-                                        <Label Style="{StaticResource LabelText}">
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="鏁呴殰"/>
-                                        <Label Style="{StaticResource LabelText}">
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="杞存姤璀�"/>
-                                        <Label Style="{StaticResource LabelText}">
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-                                    <StackPanel>
-                                        <Label Style="{StaticResource YDesc}" Content="浠g爜"/>
-                                        <Label Style="{StaticResource LabelText}">
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-                                </StackPanel>
-                            </GroupBox>
-
-                            <GroupBox Header="闄愪綅浼犳劅鍣�" Padding="10">
-                                <StackPanel Style="{StaticResource ButtonGroup}" Orientation="Vertical">
-                                    <StackPanel Orientation="Horizontal">
-                                        <Label Style="{StaticResource YDesc}" Content="浣胯兘"/>
-                                        <Label Style="{StaticResource LabelText}" BorderThickness="0,1,1,1" >
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-
-                                    <StackPanel Orientation="Horizontal">
-                                        <Label Style="{StaticResource YDesc}" Content="鍑嗗濂�"/>
-                                        <Label Style="{StaticResource LabelText}" BorderThickness="0,1,1,1" >
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-                                    <StackPanel Orientation="Horizontal">
-                                        <Label Style="{StaticResource YDesc}" Content="杩愯涓�"/>
-                                        <Label Style="{StaticResource LabelText}" BorderThickness="0,1,1,1" >
-                                            <Ellipse Height="30" Width="30" Fill="{StaticResource Normal}" />
-                                        </Label>
-                                    </StackPanel>
-                                </StackPanel>
-                            </GroupBox>
-
-                            <GroupBox Header="瀵稿姩" Padding="10">
-                                <StackPanel Style="{StaticResource ButtonGroup}">
-                                    <Button Style="{StaticResource PrimaryButton}">瀵稿姩</Button>
-
-                                    <Label Style="{StaticResource LabelText}" BorderThickness="1" Content="鍑嗗濂�"/>
-
-                                    <Button Style="{StaticResource PrimaryButton}">姝e悜</Button>
-                                </StackPanel>
-                            </GroupBox>
-
-                            <GroupBox Header="鎿嶄綔" Padding="10">
+                            <GroupBox Header="{DynamicResource App.Opt}" Padding="10">
                                 <Grid dp:GridHelper.Space="10">
                                     <Grid.RowDefinitions>
                                         <RowDefinition Height="Auto"/>
@@ -340,32 +263,251 @@
                                         <RowDefinition Height="Auto"/>
                                         <RowDefinition Height="Auto"/>
                                         <RowDefinition Height="Auto"/>
+                                        <RowDefinition Height="Auto"/>
                                     </Grid.RowDefinitions>
-                                    <Button Style="{StaticResource PrimaryButton}">璋冭瘯妯″紡</Button>
-                                    <UniformGrid Grid.Row="1" Columns="2">
+                                    <Grid>
+                                        <Grid.ColumnDefinitions>
+                                            <ColumnDefinition Width="Auto"/>
+                                            <ColumnDefinition/>
+                                        </Grid.ColumnDefinitions>
+                                        <Label 
+                                            Style="{StaticResource BDesc}" MinWidth="80" Padding="0"
+                                            Content="{DynamicResource svo.product.model}"/>
+                                        <ComboBox Grid.Column="1"  x:Name="productInput" 
+IsEnabled="{Binding HasSelectedServo}"
+SelectedValue="{Binding SelectedProduct}"
+ItemsSource="{Binding ServoProducts}"
+SelectedValuePath="ProgramCode"
+DisplayMemberPath="Model"
+                                                  BorderThickness="0,1,1,1"
+                                    FontSize="14"
+                                    BorderBrush="Black"
+Style="{StaticResource FormComboxStyle}" MinWidth="180" />
+                                    </Grid>
+
+                                    <Button Grid.Row="1" Style="{StaticResource PrimaryButton}"
+                                            Content="{DynamicResource svo.debugMode}"/>
+                                    <UniformGrid Grid.Row="2" Columns="2">
+                                        <Button Margin="0,0,5,0" Tag="Enable" Click="Servo_Click">
+                                            <Button.Style>
+                                                <Style TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
+                                                    <Setter Property="Content" Value="{DynamicResource svo.enable}"/>
+                                                    <Style.Triggers>
+                                                        <DataTrigger Binding="{Binding Enable}" Value="1">
+                                                            <Setter Property="Content" Value="{DynamicResource svo.disable}"/>
+                                                        </DataTrigger>
+                                                    </Style.Triggers>
+                                                </Style>
+                                            </Button.Style>
+                                        </Button>
                                         <Button Style="{StaticResource PrimaryButton}"
-                                                Margin="0,0,5,0">璋冭瘯妯″紡</Button>
-                                        <Button Style="{StaticResource PrimaryButton}"
-                                                Margin="5,0,0,0">璋冭瘯妯″紡</Button>
+ Margin="5,0,0,0" Content="{DynamicResource svo.reset}" Tag="Reset" Click="Servo_Click"/>
                                     </UniformGrid>
-                                    <Button Grid.Row="2" Style="{StaticResource PrimaryButton}">鍒濆鍖�</Button>
-                                    <Button Grid.Row="3" Style="{StaticResource PrimaryButton}">鍋滄</Button>
-                                    <UniformGrid Grid.Row="4" Columns="3">
-                                        <Button Style="{StaticResource PrimaryButton}">璋冭瘯妯″紡</Button>
-                                        <Label Style="{StaticResource LabelText}" 
-                                               Margin="10,0,10,0"
-                                               BorderThickness="1" Content="鍑嗗濂�"/>
-                                        <Button Style="{StaticResource PrimaryButton}">璋冭瘯妯″紡</Button>
+                                    <Button Grid.Row="3" Style="{StaticResource PrimaryButton}"
+                                            Content="{DynamicResource svo.init}"
+                                            Tag="Initialization" Click="Servo_Click"/>
+                                    <Button Grid.Row="4" Style="{StaticResource PrimaryButton}"
+                                            Content="{DynamicResource svo.stop}"
+                                            Tag="Stop" Click="Servo_Click"/>
+                                    <UniformGrid Grid.Row="5" Columns="3">
+                                        <Button Style="{StaticResource PrimaryButton}"
+                                                Content="{DynamicResource svo.JOG+}"
+                                                Tag="JoGadd" Click="Servo_Click"/>
+                                        <Label Style="{StaticResource LabelText}" MinWidth="90"
+Margin="10,0,10,0"
+BorderThickness="1" MouseLeftButtonUp="Label_MouseLeftButtonUp" Tag="JogVelocity" Content="{Binding JogVelocity}"/>
+                                        <Button Style="{StaticResource PrimaryButton}"
+                                                Content="{DynamicResource svo.JOG-}"
+                                                Tag="JOGsub" Click="Servo_Click"/>
                                     </UniformGrid>
                                 </Grid>
-                                
                             </GroupBox>
+                            <StackPanel Grid.Column="1">
+                                <GroupBox Header="{DynamicResource svo.position}">
+                                    <Grid dp:GridHelper.Space="10">
+                                        <Grid.RowDefinitions>
+                                            <RowDefinition Height="Auto"/>
+                                            <RowDefinition Height="Auto"/>
+                                        </Grid.RowDefinitions>
+                                        <Grid.ColumnDefinitions>
+                                            <ColumnDefinition/>
+                                            <ColumnDefinition/>
+                                            <ColumnDefinition/>
+                                            <ColumnDefinition/>
+                                        </Grid.ColumnDefinitions>
 
+                                        <StackPanel>
+                                            <Label Style="{StaticResource BDesc}" 
+                                               Content="{DynamicResource svo.currentPosition}"/>
+                                            <Label Style="{StaticResource ReadLabel}" Content="{Binding CurrentPosition}"/>
+                                        </StackPanel>
 
-                        </WrapPanel>
+                                        <StackPanel Grid.Column="1">
+                                            <Label Style="{StaticResource BDesc}" 
+                                               Content="{DynamicResource svo.currentSpeed}"/>
+                                            <Label Style="{StaticResource ReadLabel}" Content="{Binding CurrentSpeed}"/>
+                                        </StackPanel>
+                                        <StackPanel Grid.Column="2">
+                                            <Label Style="{StaticResource BDesc}" 
+                                               Content="{DynamicResource svo.OverAcc}"/>
+                                            <Label Style="{StaticResource LabelText}"
+                                                   MouseLeftButtonUp="Label_MouseLeftButtonUp"
+                                                   Tag="OverAcc"
+                                                   Content="{Binding OverAcc}"/>
+                                        </StackPanel>
+                                        <StackPanel Grid.Column="3">
+                                            <Label Style="{StaticResource BDesc}" 
+                                                   Content="{DynamicResource svo.OverDec}"/>
+                                            <Label Style="{StaticResource LabelText}"
+                                                   MouseLeftButtonUp="Label_MouseLeftButtonUp" 
+                                                   Tag="OverDec"
+                                                   Content="{Binding OverDec}"/>
+                                        </StackPanel>
+
+                                        <StackPanel Grid.Row="1">
+                                            <Label Style="{StaticResource BDesc}"
+                                               Content="{DynamicResource svo.HMIPosition}"/>
+                                            <Label Style="{StaticResource LabelText}" 
+                                                   MouseLeftButtonUp="Label_MouseLeftButtonUp" 
+                                                   Tag="HMIPosition" Content="{Binding HMIPosition}"/>
+                                        </StackPanel>
+
+                                        <StackPanel Grid.Row="1" Grid.Column="1">
+                                            <Label Style="{StaticResource BDesc}"
+                                               Content="{DynamicResource svo.HMISpeed}"/>
+                                            <Label Style="{StaticResource LabelText}" 
+                                                   MouseLeftButtonUp="Label_MouseLeftButtonUp" 
+                                                   Tag="HMISpeed" 
+                                                   Content="{Binding HMISpeed}"/>
+                                        </StackPanel>
+                                        <Button Grid.Row="1" Grid.Column="2" 
+                                            Grid.ColumnSpan="2" 
+                                            Style="{StaticResource PrimaryButton}"
+                                            Tag="AbsExecute"
+                                            Click="Servo_Click"
+                                            Content="{DynamicResource svo.absExecute}"/>
+                                    </Grid>
+                                </GroupBox>
+
+                                <GroupBox Header="{DynamicResource svo.inching}">
+                                    <DockPanel>
+                                        <Button DockPanel.Dock="Left" 
+                                                Margin="0,0,10,0"
+                                                Style="{StaticResource PrimaryButton}"
+                                                Tag="Inch" Click="Servo_Click"
+                                                Content="{DynamicResource svo.inching}"/>
+                                        <Button DockPanel.Dock="Right"
+                                                Tag="Dir" Click="Servo_Click">
+                                            <Button.Style>
+                                                <Style TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
+                                                    <Setter Property="Content" Value="{DynamicResource svo.forward}"/>
+                                                    <Style.Triggers>
+                                                        <DataTrigger Binding="{Binding Dir}" Value="1">
+                                                            <Setter Property="Content" Value="{DynamicResource svo.backward}"/>
+                                                        </DataTrigger>
+                                                    </Style.Triggers>
+                                                </Style>
+                                            </Button.Style>
+                                        </Button>
+                                        <Label 
+                                             Margin="0,0,10,0"
+                                            Style="{StaticResource LabelText}" 
+                                            MouseLeftButtonUp="Label_MouseLeftButtonUp"
+                                            Tag="InchDistance"
+                                            BorderThickness="1" Content="{Binding InchDistance}"/>
+                                    </DockPanel>
+                                </GroupBox>
+                            </StackPanel>
+
+                            <StackPanel Grid.Column="2" HorizontalAlignment="Center">
+                                <GroupBox Header="{DynamicResource svo.alarm}">
+                                    <StackPanel Style="{StaticResource ButtonGroup}">
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}" 
+                   Content="{DynamicResource svo.controlAlarm}"/>
+                                            <Label Style="{StaticResource ReadLabel}" Content="{Binding AlarmCode}"/>
+                                        </StackPanel>
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+                   Content="{DynamicResource svo.driverAlarm}"/>
+                                            <Label Style="{StaticResource ReadLabel}" Content="{Binding WarnCode}"/>
+                                        </StackPanel>
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}" 
+                   Content="{DynamicResource svo.faultDriven}"/>
+                                            <Label Style="{StaticResource ReadLabel}" Content="{Binding FaultCode}"/>
+                                        </StackPanel>
+                                    </StackPanel>
+                                </GroupBox>
+
+                                <GroupBox Header="{DynamicResource svo.limitSensor}">
+                                    <StackPanel Style="{StaticResource ButtonGroup}">
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}" 
+                                                   Content="{DynamicResource svo.limit+}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding PositiveLimit}" />
+                                        </StackPanel>
+
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}" 
+                                                   Content="{DynamicResource svo.limit0}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding HomeSwitch}" />
+                                        </StackPanel>
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+                                                   Content="{DynamicResource svo.limit-}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding NegativeLimit}" />
+                                        </StackPanel>
+                                    </StackPanel>
+                                </GroupBox>
+                            </StackPanel>
+
+                            <StackPanel Grid.Row="1" Grid.ColumnSpan="2">
+                                <GroupBox Header="{DynamicResource svo.status}">
+                                    <StackPanel Style="{StaticResource ButtonGroup}" HorizontalAlignment="Center">
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+                                                   Content="{DynamicResource svo.enable}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding AxisEnabled}"/>
+                                        </StackPanel>
+
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+                                                   Content="{DynamicResource svo.isReady}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding ReadyOK}" />
+                                        </StackPanel>
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+                                                   Content="{DynamicResource svo.isRunning}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding Running}" />
+                                        </StackPanel>
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+           Content="{DynamicResource svo.reOriginOk}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding Homed}" />
+                                        </StackPanel>
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+                                                   Content="{DynamicResource svo.fault}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding AxisError}" />
+                                        </StackPanel>
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+                                                   Content="{DynamicResource svo.axisAlarm}"/>
+                                            <Ellipse Style="{StaticResource LightBall}" DataContext="{Binding AxisWarn}" />
+                                        </StackPanel>
+                                        <StackPanel>
+                                            <Label Style="{StaticResource YDesc}"
+                                                   Content="{DynamicResource svo.code}"/>
+                                            <Label Style="{StaticResource ReadLabel}" Content="{Binding PosCode}"/>
+                                        </StackPanel>
+                                    </StackPanel>
+                                </GroupBox>
+                            </StackPanel>
+                        </Grid>
                     </Grid>
                 </Border>
             </DockPanel>
         </Grid>
     </Border>
-</UserControl>
+</hb:PluginControl>
diff --git a/Plugin.ServoManage/ServoManage.xaml.cs b/Plugin.ServoManage/ServoManage.xaml.cs
index d816844..76a460e 100644
--- a/Plugin.ServoManage/ServoManage.xaml.cs
+++ b/Plugin.ServoManage/ServoManage.xaml.cs
@@ -1,39 +1,724 @@
 锘縰sing HMI.Base;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.ParameterManage.Entity;
+using HMI.ParameterManage.Util;
+using HMI.UI.Util;
+using Plugin.ServoManage.Entity;
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Reflection;
+using System.Threading;
+using System.Timers;
 using System.Windows;
 using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
 
 namespace Plugin.ServoManage
 {
+    [AttributeUsage(AttributeTargets.Property)]
+    public class IsStatusAttribute : Attribute
+    {
+    }
+
     /// <summary>
     /// UserControl1.xaml 鐨勪氦浜掗�昏緫
     /// </summary>
-    public partial class ServoManage: UserControl
+    public partial class ServoManage : PluginControl
     {
+        public static string FilePath { get; private set; }
+        public static string ProductFilePath { get; private set; }
+
+        private ObservableCollection<ServoData> servos;
+        public ObservableCollection<ServoData> Servos
+        {
+            get => servos;
+            set
+            {
+                Set(ref servos, value);
+            }
+        }
+
+        private ServoData selectedServo;
+        public ServoData SelectedServo
+        {
+            get => selectedServo;
+            set
+            {
+                Set(ref selectedServo, value);
+                Set("HasSelectedServo");
+                RefreshServoStatus();
+            }
+        }
+
+        public bool HasSelectedServo
+        {
+            get => SelectedServo != null;
+        }
+
+        private string selectedProduct;
+        [IsStatus]
+        public string SelectedProduct
+        {
+            get => selectedProduct;
+            set
+            {
+                if (value != selectedProduct)
+                {
+                    Set(ref selectedProduct, value);
+                    if (SelectedServo != null)
+                    {
+                        SetBitValue($"{SelectedServo.Name}_sRecipeCode", value);
+                    }
+                }
+            }
+        }
+
+        private ObservableCollection<ServoProductData> servoProducts;
+        public ObservableCollection<ServoProductData> ServoProducts
+        {
+            get => servoProducts;
+            set
+            {
+                Set(ref servoProducts, value);
+            }
+        }
+
+        /// <summary>
+        /// 瀹炰緥鍖栨湇鍔″櫒鎺ュ彛鍑芥暟
+        /// </summary>
+        private OpcInterface.OpcInterface lTSCADAApi = new OpcInterface.OpcInterface();
+        private bool isActived = false;
+        private System.Timers.Timer motorMonitorTimer;
+
+        private string enable;
+        [IsStatus]
+        public string Enable
+        {
+            get => enable;
+            set
+            {
+                Set(ref enable, value);
+            }
+        }
+
+        private string currentPosition;
+        [IsStatus]
+        public string CurrentPosition
+        {
+            get => $"{currentPosition}{SelectedServo?.Unit}";
+            set
+            {
+                Set(ref currentPosition, value);
+            }
+        }
+
+        private string currentSpeed;
+        [IsStatus]
+        public string CurrentSpeed
+        {
+            get => $"{currentSpeed}{SelectedServo?.Unit}/s";
+            set
+            {
+                Set(ref currentSpeed, value);
+            }
+        }
+
+        private string overAcc;
+        [IsStatus]
+        public string OverAcc
+        {
+            get => $"{overAcc}{SelectedServo?.Unit}/s虏";
+            set
+            {
+                Set(ref overAcc, value);
+            }
+        }
+
+        private string overDec;
+        [IsStatus]
+        public string OverDec
+        {
+            get => $"{overDec}{SelectedServo?.Unit}/s虏";
+            set
+            {
+                Set(ref overDec, value);
+            }
+        }
+
+        private string hmiPosition;
+        [IsStatus]
+        public string HMIPosition
+        {
+            get => $"{hmiPosition}{SelectedServo?.Unit}";
+            set
+            {
+                Set(ref hmiPosition, value);
+            }
+        }
+
+        private string hmiSpeed;
+        [IsStatus]
+        public string HMISpeed
+        {
+            get => $"{hmiSpeed}{SelectedServo?.Unit}/s";
+            set
+            {
+                Set(ref hmiSpeed, value);
+            }
+        }
+
+        private string jogVelocity;
+        [IsStatus]
+        public string JogVelocity
+        {
+            get => $"{jogVelocity}%";
+            set
+            {
+                Set(ref jogVelocity, value);
+            }
+        }
+
+        private string inchDistance;
+        [IsStatus]
+        public string InchDistance
+        {
+            get => $"{inchDistance}{SelectedServo?.Unit}";
+            set
+            {
+                Set(ref inchDistance, value);
+            }
+        }
+
+        private string dir;
+        [IsStatus]
+        public string Dir
+        {
+            get => dir;
+            set
+            {
+                Set(ref dir, value);
+            }
+        }
+
+        private string alarmCode = "0";
+        [IsStatus]
+        public string AlarmCode
+        {
+            get => alarmCode;
+            set
+            {
+                Set(ref alarmCode, value);
+            }
+        }
+
+        private string warnCode = "0";
+        [IsStatus]
+        public string WarnCode
+        {
+            get => warnCode;
+            set
+            {
+                Set(ref warnCode, value);
+            }
+        }
+
+        private string faultCode = "0";
+        [IsStatus]
+        public string FaultCode
+        {
+            get => faultCode;
+            set
+            {
+                Set(ref faultCode, value);
+            }
+        }
+
+        private string positiveLimit;
+        [IsStatus]
+        public string PositiveLimit
+        {
+            get => positiveLimit;
+            set
+            {
+                Set(ref positiveLimit, value);
+            }
+        }
+
+        private string homeSwitch;
+        [IsStatus]
+        public string HomeSwitch
+        {
+            get => homeSwitch;
+            set
+            {
+                Set(ref homeSwitch, value);
+            }
+        }
+
+        private string negativeLimit;
+        [IsStatus]
+        public string NegativeLimit
+        {
+            get => negativeLimit;
+            set
+            {
+                Set(ref negativeLimit, value);
+            }
+        }
+
+        private string axisEnabled;
+        [IsStatus]
+        public string AxisEnabled
+        {
+            get => axisEnabled;
+            set
+            {
+                Set(ref axisEnabled, value);
+            }
+        }
+
+        private string readyOK;
+        [IsStatus]
+        public string ReadyOK
+        {
+            get => readyOK;
+            set
+            {
+                Set(ref readyOK, value);
+            }
+        }
+
+        private string running;
+        [IsStatus]
+        public string Running
+        {
+            get => running;
+            set
+            {
+                Set(ref running, value);
+            }
+        }
+
+        private string homed;
+        [IsStatus]
+        public string Homed
+        {
+            get => homed;
+            set
+            {
+                Set(ref homed, value);
+            }
+        }
+
+        private string axisError;
+        [IsStatus]
+        public string AxisError
+        {
+            get => axisError;
+            set
+            {
+                Set(ref axisError, value);
+            }
+        }
+
+        private string axisWarn;
+        [IsStatus]
+        public string AxisWarn
+        {
+            get => axisWarn;
+            set
+            {
+                Set(ref axisWarn, value);
+            }
+        }
+
+        private string posCode = "0";
+        [IsStatus]
+        public string PosCode
+        {
+            get => posCode;
+            set
+            {
+                Set(ref posCode, value);
+            }
+        }
+
         public ServoManage()
         {
+            DataContext = this;
+            motorMonitorTimer = new System.Timers.Timer();
+            motorMonitorTimer.Elapsed += MotorMonitorTimer_Elapsed;
             InitializeComponent();
+        }
+
+        private void MotorMonitorTimer_Elapsed(object sender, ElapsedEventArgs e)
+        {
+            this.motorMonitorTimer.Enabled = false;
+            try
+            {
+                RefreshServoStatus();
+                this.motorMonitorTimer.Enabled = true;
+            }
+            catch (Exception ex)
+            {
+                this.motorMonitorTimer.Enabled = true;
+                return;
+            }
+        }
+
+        public override void SetBaseFolder(string folder)
+        {
+            FilePath = Path.Combine(folder, "Servo.data");
+            ProductFilePath = Path.Combine(folder, "ServoProduct.data");
+            base.SetBaseFolder(folder);
+        }
+
+        public override void Active()
+        {
+            base.Active();
+            if (!isActived)
+            {
+                try
+                {
+                    if (SystemSetting.Instance.PlcEnabled)
+                    {
+                        if (lTSCADAApi.Connect2("127.0.0.1", 6543, 18888, out string errMsg))
+                        {
+                            this.motorMonitorTimer.Interval = 100;
+                            this.motorMonitorTimer.Start();
+                            isActived = true;
+                        }
+                        else
+                        {
+                            MsgBoxHelper2.Error(errMsg);
+                        }
+                    }
+                    else
+                    {
+
+                        isActived = true;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    log.Error("Active Failed.", ex);
+                    MsgBoxHelper2.Error(ex.Message);
+                }
+            }
         }
 
         private void UserControl_Loaded(object sender, RoutedEventArgs e)
         {
-
+            LoadData();
+            LoadProductData();
+            this.Loaded -= UserControl_Loaded;
         }
 
         private void Button_Click(object sender, RoutedEventArgs e)
         {
+            Button btn = sender as Button;
+            ServoData data = btn.DataContext as ServoData;
+            switch (btn.Name)
+            {
+                case "addServoBtn":
+                    OpenServoModal(null);
+                    break;
+                case "editServoBtn":
+                    OpenServoModal(data);
+                    break;
+                case "delServoBtn":
+                    TryDeleteServo(data);
+                    break;
+                case "rfhServoBtn":
+                    LoadData();
+                    break;
 
+                case "addProductBtn":
+                    OpenProductModal(null);
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        #region Servo
+        private void LoadData()
+        {
+            try
+            {
+                ObservableCollection<ServoData> data = new ObservableCollection<ServoData>();
+                if (File.Exists(FilePath))
+                {
+                    data = XmlHelper.DeserializeFromXml<ObservableCollection<ServoData>>(FilePath);
+                }
+                Servos = data;
+            }
+            catch (Exception ex)
+            {
+                log.Error("Load Servo Data Failed.", ex);
+                ToastHelper.Error(this.lang("App.LoadFailed"));
+            }
+        }
+
+        private void OpenServoModal(ServoData data)
+        {
+            bool isUpdate = data != null;
+            try
+            {
+
+                ServoModal modal = new ServoModal
+                {
+                    Title = isUpdate ? this.lang("App.Edit") : this.lang("App.Add"),
+                    Owner = Window.GetWindow(this)
+                };
+                if (modal.Open(data ?? new ServoData(), Servos) == true)
+                {
+                    LoadData();
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error($"Add Or Edit Data Failed.", ex);
+                var title = isUpdate ? this.lang("App.EditFailed") : this.lang("App.AddFailed");
+                MsgBoxHelper2.Error($"{title}: {ex.Message}");
+            }
+        }
+
+        private void TryDeleteServo(ServoData data)
+        {
+            try
+            {
+                if (MsgBoxHelper2.WarnChoose(this.lang("HMI.MakeSureDeleteSingle", data.Name)) == MessageBoxResult.OK)
+                {
+                    int index = Servos.IndexOf(data);
+                    if (index > 0)
+                    {
+                        var temp = XmlHelper.DeepClone(Servos);
+                        temp.RemoveAt(index);
+                        XmlHelper.SerializeToXml(FilePath, temp);
+                    }
+                    LoadData();
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error($"Delete Servo Failed.", ex);
+                MsgBoxHelper2.Error($"{this.lang("App.DeleteFailed")}: {ex.Message}");
+            }
+        }
+        #endregion
+
+        #region product
+        public ObservableCollection<ServoProductData> ReadCommonProducts()
+        {
+            ObservableCollection<ServoProductData> datas = new ObservableCollection<ServoProductData>();
+            List<ProductData> products = ParameterManager.GetProducts<List<ProductData>>();
+            if (products != null && products.Count > 0)
+            {
+                foreach (var product in products)
+                {
+                    var parameter = ParameterManager.GetParametersByProductName(product.Name)
+                         ?.FirstOrDefault(p => p.Name == "ProgramCode");
+                    if (parameter != null)
+                    {
+                        datas.Add(new ServoProductData
+                        {
+                            Model = product.Name,
+                            ProgramCode = parameter.Value,
+                        });
+                    }
+                }
+            }
+            return datas;
+        }
+
+        private void LoadProductData()
+        {
+            try
+            {
+                //ObservableCollection<ServoProductData> datas = new ObservableCollection<ServoProductData>();
+                //if (File.Exists(FilePath))
+                //{
+                //    datas = XmlHelper.DeserializeFromXml<ObservableCollection<ServoProductData>>(ProductFilePath);
+                //}
+                ServoProducts = ReadCommonProducts();
+            }
+            catch (Exception ex)
+            {
+                log.Error("Load Servo Product Data Failed.", ex);
+                ToastHelper.Error(this.lang("App.LoadFailed"));
+            }
+        }
+
+        private void OpenProductModal(ServoProductData data)
+        {
+            bool isUpdate = data != null;
+            try
+            {
+
+                ServoProductModal modal = new ServoProductModal
+                {
+                    Title = isUpdate ? this.lang("App.Edit") : this.lang("App.Add"),
+                    Owner = Window.GetWindow(this)
+                };
+                if (modal.Open(data ?? new ServoProductData(), ServoProducts) == true)
+                {
+                    LoadProductData();
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error($"Add Or Edit Product Data Failed.", ex);
+                var title = isUpdate ? this.lang("App.EditFailed") : this.lang("App.AddFailed");
+                MsgBoxHelper2.Error($"{title}: {ex.Message}");
+            }
+        }
+        #endregion
+
+        private void RefreshServoStatus()
+        {
+            Dispatcher.Invoke(() =>
+            {
+                if (SelectedServo == null) return;
+                PropertyInfo[] properties = this.GetType().GetProperties();
+                foreach (var prop in properties)
+                {
+                    if (!Attribute.IsDefined(prop, typeof(IsStatusAttribute)))
+                    {
+                        continue;
+                    }
+
+                    if (prop.Name == "SelectedProduct")
+                    {
+                        var data = GetBitValue($"{SelectedServo.Name}_sRecipeCode");
+                        SelectedProduct = data;
+                    }
+                    else
+                    {
+                        var data = GetBitValue($"{SelectedServo.Name}_{prop.Name}");
+                        prop.SetValue(this, data);
+                    }
+                }
+            });
+        }
+
+        /// <summary>
+        /// 璁剧疆DB鍦板潃bool鍊�
+        /// </summary>
+        /// <param name="subbuttonX">瀛愭寜閽�</param>
+        /// <param name="address">鍦板潃</param>
+        /// <param name="bol">鍊�</param>
+        private void SetBitValue(string tag, string val)
+        {
+            if (!lTSCADAApi.DoFctWriteSingle(tag, val, out string errMsg))
+            {
+                log.Error($"Set Bit Value Failed.{errMsg}");
+                MsgBoxHelper2.Error(errMsg);
+            }
+        }
+
+        /// <summary>
+        /// 閫氳繃褰撳墠鏍囩璇诲彇鍊�
+        /// </summary>
+        /// <param name="tag">鏍囩</param>
+        /// <returns>杩斿洖鍊�</returns>
+        private string GetBitValue(string tag)
+        {
+            if (lTSCADAApi.DoFctReadSingle(tag, out string res, out string err))
+            {
+                return res;
+            }
+            else
+            {
+                return "";
+            }
+        }
+
+        private void Servo_Click(object sender, RoutedEventArgs e)
+        {
+            if (SelectedServo == null)
+            {
+                ToastHelper.Warning(this.lang("svo.selectAServo"));
+                return;
+            }
+            Button btn = sender as Button;
+            try
+            {
+                motorMonitorTimer.Enabled = false;
+                switch (btn.Tag)
+                {
+                    case "Enable":
+                        EnableDoClick(btn.Tag.ToString());
+                        break;
+                    case "Dir":
+                        EnableDoClick(btn.Tag.ToString());
+                        break;
+                    default:
+                        DoSignClick(btn.Tag?.ToString());
+                        break;
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error($"Servo Opt Failed, BtnName is {btn.Name}", ex);
+                MsgBoxHelper2.Error(ex.Message);
+            }
+            finally
+            {
+                motorMonitorTimer.Enabled = true;
+            }
+        }
+
+        private void DoSignClick(string tag)
+        {
+            if (!string.IsNullOrEmpty(tag))
+            {
+                SetBitValue($"{SelectedServo?.Name}_{tag}", "true");
+                Thread.Sleep(50);
+                SetBitValue($"{SelectedServo?.Name}_{tag}", "false");
+            }
+        }
+
+        /// <summary>
+        /// 浣胯兘/鏂娇鑳� 鎸夐挳
+        /// </summary>
+        /// <param name="btnName"></param>
+        private void EnableDoClick(string btnName)
+        {
+            bool val = GetBitValue($"{SelectedServo?.Name}_{btnName}") == "1";
+            SetBitValue($"{SelectedServo?.Name}_{btnName}", $"{(!val ? 1 : 0)}");
+        }
+
+        private void Label_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        {
+            if (SelectedServo == null)
+            {
+                ToastHelper.Warning(this.lang("svo.selectAServo"));
+                return;
+            }
+            Label label = sender as Label;
+            var tag = label.Tag.ToString();
+            NumberPanel np = new NumberPanel()
+            {
+                Title = this.lang($"svo.{tag}"),
+                Owner = Window.GetWindow(this)
+            };
+            string value = label.Content.ToString();
+            if (value.Contains("%"))
+            {
+                value = value.Replace("%", "");
+            }
+            else if (SelectedServo != null)
+            {
+                value = value.Split(new string[] { SelectedServo.Unit }, StringSplitOptions.None)[0];
+            }
+            if (np.Open(value) == true)
+            {
+                SetBitValue($"{SelectedServo?.Name}_{tag}", np.Data?.ToString());
+            }
         }
     }
 }
diff --git a/Plugin.ServoManage/ServoModal.xaml b/Plugin.ServoManage/ServoModal.xaml
new file mode 100644
index 0000000..4a60f3e
--- /dev/null
+++ b/Plugin.ServoManage/ServoModal.xaml
@@ -0,0 +1,37 @@
+锘�<pu:WindowX x:Class="Plugin.ServoManage.ServoModal"
+            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+            xmlns:local="clr-namespace:Plugin.ServoManage"
+            xmlns:pw="https://opensource.panuon.com/wpf"
+            xmlns:pu="https://opensource.panuon.com/wpf-ui"
+            xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+            xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+            mc:Ignorable="d"
+            Title="Form"
+            SizeToContent="Height"
+            Width="600"
+            WindowStartupLocation="CenterOwner"
+            Style="{StaticResource ModalWindow}">
+    <Grid Margin="10">
+        <StackPanel x:Name="formPanel">
+            <pu:FormGroup x:Name="FgName" Style="{StaticResource InputFormGroupStyle}" 
+                          Header="{DynamicResource svo.name}"
+                          dp:FormGroupHelper.IsRequired="True" 
+                          dp:FormGroupHelper.ValidateMethod="ValidateName"
+                          GroupName="MyFormGroup">
+                <TextBox x:Name="TbName" Style="{StaticResource EditorTextBoxStyle}" />
+            </pu:FormGroup>
+
+            <pu:FormGroup x:Name="FgUnit" Style="{StaticResource InputFormGroupStyle}"
+                         Header="{DynamicResource svo.unit}" 
+                         dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+                <ComboBox x:Name="CbUnit" Style="{StaticResource FormComboxStyle}" SelectedValuePath="Content">
+                    <ComboBoxItem>mm</ComboBoxItem>
+                    <ComboBoxItem>掳</ComboBoxItem>
+                </ComboBox>
+            </pu:FormGroup>
+        </StackPanel>
+    </Grid>
+</pu:WindowX>
diff --git a/Plugin.ServoManage/ServoModal.xaml.cs b/Plugin.ServoManage/ServoModal.xaml.cs
new file mode 100644
index 0000000..bf9b2c9
--- /dev/null
+++ b/Plugin.ServoManage/ServoModal.xaml.cs
@@ -0,0 +1,126 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.DpUtil;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using Plugin.ServoManage.Entity;
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+
+namespace Plugin.ServoManage
+{
+    /// <summary>
+    /// ModalWindow.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class ServoModal : WindowX
+    {
+        public ServoModal()
+        {
+            this.DataContext = this;
+            InitializeComponent();
+        }
+
+        public ServoData Data { get; set; }
+        private ObservableCollection<ServoData> Datasource;
+
+        private bool _isProcessing;
+
+        protected override void OnClosing(CancelEventArgs e)
+        {
+            //Press Continue Button
+            if (DialogResult == true)
+            {
+                if (_isProcessing)
+                {
+                    e.Cancel = true;
+                    return;
+                }
+                var okButton = WindowXModalDialog.GetOKButton(this);
+                try
+                {
+                    _isProcessing = true;
+                    ButtonHelper.SetIsPending(okButton, true);
+                    if (!ValidateForm())
+                    {
+                        e.Cancel = true;
+                        return;
+                    }
+
+                    SaveOrUpdateData();
+                }
+                catch (Exception ex)
+                {
+                    ToastHelper.Error(this, $"Error锛亄ex.Message}");
+                    e.Cancel = true;
+                    return;
+                }
+                finally
+                {
+                    _isProcessing = false;
+                    ButtonHelper.SetIsPending(okButton, false);
+                }
+            }
+            base.OnClosing(e);
+        }
+
+        private bool ValidateName(object value, out string err)
+        {
+            err = null;
+            var data = Datasource?.FirstOrDefault(d => d.Name == value.ToString());
+            if (data != null && data != Data)
+            {
+                err = string.Format(LangUtil.Get("App.MustBeUnique"), LangUtil.Get("svo.name"));
+                return false;
+            }
+            return true;
+        }
+
+        private bool ValidateForm()
+        {
+            bool flag = FormGroupHelper.ValidateForm(formPanel);
+            if (flag)
+            {
+                Data.Name = TbName.Text;
+                Data.Unit = CbUnit.Text;
+            }
+
+            return flag;
+        }
+
+        public bool? Open(ServoData data, ObservableCollection<ServoData> datasource)
+        {
+            Datasource = datasource;
+            Data = data;
+            TbName.Text = Data.Name;
+            CbUnit.SelectedValue = Data.Unit;
+            return this.ShowDialog();
+        }
+
+        private void SaveOrUpdateData()
+        {
+            int index = Datasource.IndexOf(Data);
+            if (index < 0)
+            {
+                InsertData(Data);
+            }
+            else
+            {
+                UpdateData(index, Data);
+            }
+        }
+
+        public void InsertData(ServoData data)
+        {
+            Datasource.Add(data);
+            XmlHelper.SerializeToXml(ServoManage.FilePath, Datasource);
+        }
+
+        public void UpdateData(int index, ServoData data)
+        {
+            var temp = XmlHelper.DeepClone(Datasource);
+            temp[index] = data;
+            XmlHelper.SerializeToXml(ServoManage.FilePath, Datasource);
+        }
+    }
+}
diff --git a/Plugin.ServoManage/ServoProductModal.xaml b/Plugin.ServoManage/ServoProductModal.xaml
new file mode 100644
index 0000000..07a9c27
--- /dev/null
+++ b/Plugin.ServoManage/ServoProductModal.xaml
@@ -0,0 +1,34 @@
+锘�<pu:WindowX x:Class="Plugin.ServoManage.ServoProductModal"
+            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+            xmlns:local="clr-namespace:Plugin.ServoManage"
+            xmlns:pw="https://opensource.panuon.com/wpf"
+            xmlns:pu="https://opensource.panuon.com/wpf-ui"
+            xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+            xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+            mc:Ignorable="d"
+            Title="Form"
+            SizeToContent="Height"
+            Width="600"
+            WindowStartupLocation="CenterOwner"
+            Style="{StaticResource ModalWindow}">
+    <Grid Margin="10">
+        <StackPanel x:Name="formPanel">
+            <pu:FormGroup x:Name="FgModel" Style="{StaticResource InputFormGroupStyle}" 
+                          Header="{DynamicResource svo.product.model}"
+                         dp:FormGroupHelper.ValidateMethod="ValidateModel"
+                          dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+                <TextBox x:Name="TbModel" Style="{StaticResource EditorTextBoxStyle}" />
+            </pu:FormGroup>
+
+            <pu:FormGroup x:Name="FgProgramCode" Style="{StaticResource InputFormGroupStyle}"
+                         dp:FormGroupHelper.ValidateMethod="ValidateProgramCode"
+                         Header="{DynamicResource svo.product.programCode}" 
+                         dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+                <pu:NumberInput x:Name="NiProgramCode" Style="{StaticResource FormNumberInput}" />
+            </pu:FormGroup>
+        </StackPanel>
+    </Grid>
+</pu:WindowX>
diff --git a/Plugin.ServoManage/ServoProductModal.xaml.cs b/Plugin.ServoManage/ServoProductModal.xaml.cs
new file mode 100644
index 0000000..997c415
--- /dev/null
+++ b/Plugin.ServoManage/ServoProductModal.xaml.cs
@@ -0,0 +1,138 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.DpUtil;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using Plugin.ServoManage.Entity;
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+
+namespace Plugin.ServoManage
+{
+    /// <summary>
+    /// ModalWindow.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class ServoProductModal : WindowX
+    {
+        public ServoProductModal()
+        {
+            this.DataContext = this;
+            InitializeComponent();
+        }
+
+        public ServoProductData Data { get; set; }
+        private ObservableCollection<ServoProductData> Datasource;
+
+        private bool _isProcessing;
+
+        protected override void OnClosing(CancelEventArgs e)
+        {
+            //Press Continue Button
+            if (DialogResult == true)
+            {
+                if (_isProcessing)
+                {
+                    e.Cancel = true;
+                    return;
+                }
+                var okButton = WindowXModalDialog.GetOKButton(this);
+                try
+                {
+                    _isProcessing = true;
+                    ButtonHelper.SetIsPending(okButton, true);
+                    if (!ValidateForm())
+                    {
+                        e.Cancel = true;
+                        return;
+                    }
+
+                    SaveOrUpdateData();
+                }
+                catch (Exception ex)
+                {
+                    ToastHelper.Error(this, $"Error锛亄ex.Message}");
+                    e.Cancel = true;
+                    return;
+                }
+                finally
+                {
+                    _isProcessing = false;
+                    ButtonHelper.SetIsPending(okButton, false);
+                }
+            }
+            base.OnClosing(e);
+        }
+
+        private bool ValidateModel(object value, out string err)
+        {
+            err = null;
+            var data = Datasource?.FirstOrDefault(d => d.Model == value.ToString());
+            if (data != null && data != Data)
+            {
+                err = string.Format(LangUtil.Get("App.MustBeUnique"), LangUtil.Get("svo.product.model"));
+                return false;
+            }
+            return true;
+        }
+
+        private bool ValidateProgramCode(object value, out string err)
+        {
+            err = null;
+            var data = Datasource?.FirstOrDefault(d => d.ProgramCode == value.ToString());
+            if (data != null && data != Data)
+            {
+                err = string.Format(LangUtil.Get("App.MustBeUnique"), LangUtil.Get("svo.product.programCode"));
+                return false;
+            }
+            return true;
+        }
+
+        private bool ValidateForm()
+        {
+            bool flag = FormGroupHelper.ValidateForm(formPanel);
+            if (flag)
+            {
+                Data.Model = TbModel.Text;
+                Data.ProgramCode = NiProgramCode.Value?.ToString();
+            }
+
+            return flag;
+        }
+
+        public bool? Open(ServoProductData data, ObservableCollection<ServoProductData> datasource)
+        {
+            Datasource = datasource ?? new ObservableCollection<ServoProductData>();
+            Data = data;
+            TbModel.Text = Data.Model;
+            NiProgramCode.Value = int.Parse(Data.ProgramCode ?? "0");
+            return this.ShowDialog();
+        }
+
+        private void SaveOrUpdateData()
+        {
+            int index = Datasource.IndexOf(Data);
+            if (index < 0)
+            {
+                InsertData(Data);
+            }
+            else
+            {
+                UpdateData(index, Data);
+            }
+        }
+
+        public void InsertData(ServoProductData data)
+        {
+            Datasource.Add(data);
+            XmlHelper.SerializeToXml(ServoManage.ProductFilePath, Datasource);
+        }
+
+        public void UpdateData(int index, ServoProductData data)
+        {
+            var temp = XmlHelper.DeepClone(Datasource);
+            temp[index] = data;
+            XmlHelper.SerializeToXml(ServoManage.ProductFilePath, Datasource);
+        }
+    }
+}
diff --git a/Plugin.ServoManage/ServoSetting.xaml b/Plugin.ServoManage/ServoSetting.xaml
new file mode 100644
index 0000000..e284bb5
--- /dev/null
+++ b/Plugin.ServoManage/ServoSetting.xaml
@@ -0,0 +1,10 @@
+锘�<UserControl x:Class="Plugin.ServoManage.ServoSetting"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:Plugin.ServoManage"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800">
+    
+</UserControl>
diff --git a/Plugin.ServoManage/ServoSetting.xaml.cs b/Plugin.ServoManage/ServoSetting.xaml.cs
new file mode 100644
index 0000000..92c2fe8
--- /dev/null
+++ b/Plugin.ServoManage/ServoSetting.xaml.cs
@@ -0,0 +1,28 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Plugin.ServoManage
+{
+    /// <summary>
+    /// ServoSetting.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class ServoSetting : UserControl
+    {
+        public ServoSetting()
+        {
+            InitializeComponent();
+        }
+    }
+}
diff --git a/Plugin.ServoManage/packages.config b/Plugin.ServoManage/packages.config
index 21b491c..c3ebe09 100644
--- a/Plugin.ServoManage/packages.config
+++ b/Plugin.ServoManage/packages.config
@@ -2,5 +2,5 @@
 <packages>
   <package id="log4net" version="3.0.4" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
 </packages>
\ No newline at end of file
diff --git a/Plugin.TestResult/Plugin.TestResult.csproj b/Plugin.TestResult/Plugin.TestResult.csproj
index 47d09d8..9ec1f6d 100644
--- a/Plugin.TestResult/Plugin.TestResult.csproj
+++ b/Plugin.TestResult/Plugin.TestResult.csproj
@@ -99,8 +99,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="ScottPlot, Version=5.0.47.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\ScottPlot.5.0.47\lib\net462\ScottPlot.dll</HintPath>
diff --git a/Plugin.TestResult/packages.config b/Plugin.TestResult/packages.config
index 0b67ea1..99ba37c 100644
--- a/Plugin.TestResult/packages.config
+++ b/Plugin.TestResult/packages.config
@@ -8,7 +8,7 @@
   <package id="OpenTK" version="3.3.1" targetFramework="net472" />
   <package id="OpenTK.GLWpfControl" version="3.3.0" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
   <package id="ScottPlot" version="5.0.47" targetFramework="net472" />
   <package id="ScottPlot.WPF" version="5.0.47" targetFramework="net472" />
   <package id="SkiaSharp" version="2.88.9" targetFramework="net472" />
diff --git a/Plugin.TsExecution/Plugin.TsExecution.csproj b/Plugin.TsExecution/Plugin.TsExecution.csproj
index 16de6e0..badc773 100644
--- a/Plugin.TsExecution/Plugin.TsExecution.csproj
+++ b/Plugin.TsExecution/Plugin.TsExecution.csproj
@@ -74,8 +74,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="ScottPlot, Version=5.0.54.0, Culture=neutral, PublicKeyToken=86698dc10387c39e, processorArchitecture=MSIL">
       <HintPath>..\WPFProject\packages\ScottPlot.5.0.54\lib\net462\ScottPlot.dll</HintPath>
diff --git a/Plugin.TsExecution/TsExecution.xaml b/Plugin.TsExecution/TsExecution.xaml
index 4472a40..1ca1f5e 100644
--- a/Plugin.TsExecution/TsExecution.xaml
+++ b/Plugin.TsExecution/TsExecution.xaml
@@ -22,12 +22,21 @@
             <ColumnDefinition Width="2*"/>
         </Grid.ColumnDefinitions>
         <WindowsFormsHost x:Name="host" Visibility="Collapsed"></WindowsFormsHost>
-        <Border>
+
+        <Grid>
+            <Grid.RowDefinitions>
+                <RowDefinition/>
+                <RowDefinition Height="Auto"/>
+            </Grid.RowDefinitions>
             <UniformGrid x:Name="panel" Columns="2" dp:UniformGridHelper.InnerBorder="1" 
                          dp:UniformGridHelper.InnerBorderBrush="#3a3a3a">
 
             </UniformGrid>
-        </Border>
+            <Border Grid.Row="1" Visibility="{Binding AlarmVisiable,Converter={StaticResource vbConverter}}" 
+                     Height="50" Background="Red"/>
+        </Grid>
+
+        
 
         <Grid Grid.Column="1">
             <Grid.RowDefinitions>
diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index c06a55f..a674983 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -106,6 +106,16 @@
         private Pie pie;
         private string CountIniPath;
 
+        private bool alarmVisiable;
+        public bool AlarmVisiable
+        {
+            get => alarmVisiable;
+            set
+            {
+                Set(ref alarmVisiable, value);
+            }
+        }
+
         public TsExecution()
         {
             DataContext = this;
diff --git a/Plugin.TsExecution/packages.config b/Plugin.TsExecution/packages.config
index 5f0c729..28ef986 100644
--- a/Plugin.TsExecution/packages.config
+++ b/Plugin.TsExecution/packages.config
@@ -8,7 +8,7 @@
   <package id="OpenTK" version="3.3.1" targetFramework="net472" />
   <package id="OpenTK.GLWpfControl" version="3.3.0" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
   <package id="ScottPlot" version="5.0.54" targetFramework="net472" />
   <package id="ScottPlot.WPF" version="5.0.54" targetFramework="net472" />
   <package id="SkiaSharp" version="2.88.9" targetFramework="net472" />
diff --git a/WPFProject/App.config b/WPFProject/App.config
index dbe641b..24552f6 100644
--- a/WPFProject/App.config
+++ b/WPFProject/App.config
@@ -5,7 +5,7 @@
 	</startup>
 	<runtime>
 		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-			<probing privatePath="Libs;ThirdParty;Plugin;3rds;"/>
+			<probing privatePath="Libs;ThirdParty;Plugin;3rds;" />
 			<dependentAssembly>
 				<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
 				<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
diff --git a/WPFProject/Lang/en-US/ServoManage.json b/WPFProject/Lang/en-US/ServoManage.json
new file mode 100644
index 0000000..c3ba147
--- /dev/null
+++ b/WPFProject/Lang/en-US/ServoManage.json
@@ -0,0 +1,45 @@
+{
+  "svo.title": "Servo manage",
+  "svo.list": "Servo list",
+  "svo.name": "Name",
+  "svo.unit": "Unit",
+  "svo.debugMode": "Debug mode",
+  "svo.enable": "Enable",
+  "svo.disable": "Disable",
+  "svo.reset": "Reset",
+  "svo.init": "Init",
+  "svo.stop": "Stop",
+  "svo.JOG+": "JOG+",
+  "svo.JogVelocity": "JOG",
+  "svo.JOG-": "JOG-",
+  "svo.position": "Position",
+  "svo.currentPosition": "Cur Position",
+  "svo.currentSpeed": "Cur Speed",
+  "svo.OverAcc": "Acc",
+  "svo.OverDec": "Decc",
+  "svo.HMIPosition": "HMI Position",
+  "svo.HMISpeed": "HMI Speed",
+  "svo.absExecute": "Abs Execute",
+  "svo.inching": "Inch",
+  "svo.InchDistance": "Inch",
+  "svo.forward": "Forward",
+  "svo.backward": "Backward",
+  "svo.limitSensor": "Limit sensor",
+  "svo.limit+": "Positive limit",
+  "svo.limit0": "Home",
+  "svo.limit-": "Negative limit",
+  "svo.isReady": "Ready",
+  "svo.isRunning": "Running",
+  "svo.alarm": "Alarm",
+  "svo.controlAlarm": "Control Alarm",
+  "svo.driverAlarm": "Driver Alarm",
+  "svo.faultDriven": "Fault Driven",
+  "svo.status": "Status",
+  "svo.reOriginOk": "Homed",
+  "svo.fault": "Fault",
+  "svo.axisAlarm": "Axis Alarm",
+  "svo.code": "Code",
+  "svo.product.model": "Model",
+  "svo.product.programCode": "Program code",
+  "svo.selectAServo": "Please select a servo"
+}
\ No newline at end of file
diff --git a/WPFProject/Lang/zh-CN/ServoManage.json b/WPFProject/Lang/zh-CN/ServoManage.json
index 929f988..bb5279c 100644
--- a/WPFProject/Lang/zh-CN/ServoManage.json
+++ b/WPFProject/Lang/zh-CN/ServoManage.json
@@ -2,5 +2,44 @@
   "svo.title": "浼烘湇绠$悊",
   "svo.list": "浼烘湇鍒楄〃",
   "svo.name": "鍚嶇О",
-  "svo.product": "浜у搧鍨嬪彿",
+  "svo.unit": "鍗曚綅",
+  "svo.debugMode": "璋冭瘯妯″紡",
+  "svo.enable": "浣胯兘",
+  "svo.disable": "鏂娇鑳�",
+  "svo.reset": "澶嶄綅",
+  "svo.init": "鍒濆鍖�",
+  "svo.stop": "鍋滄",
+  "svo.JOG+": "JOG+",
+  "svo.JogVelocity": "JOG",
+  "svo.JOG-": "JOG-",
+  "svo.position": "浣嶇疆",
+  "svo.currentPosition": "褰撳墠浣嶇疆",
+  "svo.currentSpeed": "褰撳墠閫熷害",
+  "svo.OverAcc": "鍔犻�熷害",
+  "svo.OverDec": "鍑忛�熷害",
+  "svo.HMIPosition": "鍐欏叆浣嶇疆",
+  "svo.HMISpeed": "鍐欏叆閫熷害",
+  "svo.absExecute": "缁濆鎵ц",
+  "svo.inching": "瀵稿姩",
+  "svo.InchDistance": "瀵稿姩",
+  "svo.forward": "姝e悜",
+  "svo.backward": "鍙嶅悜",
+  "svo.limitSensor": "闄愪綅浼犳劅鍣�",
+  "svo.limit+": "姝i檺浣�",
+  "svo.limit0": "鍘熺偣",
+  "svo.limit-": "璐熼檺浣�",
+  "svo.isReady": "鍑嗗濂�",
+  "svo.isRunning": "杩愯涓�",
+  "svo.alarm": "鎶ヨ",
+  "svo.controlAlarm": "鎺у埗鎶ヨ",
+  "svo.driverAlarm": "椹卞姩鎶ヨ",
+  "svo.faultDriven": "鏁呴殰椹卞姩",
+  "svo.status": "鐘舵��",
+  "svo.reOriginOk": "鍥炲師OK",
+  "svo.fault": "鏁呴殰",
+  "svo.axisAlarm": "杞存姤璀�",
+  "svo.code": "浠g爜",
+  "svo.product.model": "浜у搧鍨嬪彿",
+  "svo.product.programCode": "绋嬪簭鍙�",
+  "svo.selectAServo": "璇峰厛閫夋嫨瑕佹墽琛岀殑浼烘湇"
 }
\ No newline at end of file
diff --git a/WPFProject/PanuonWindow.xaml b/WPFProject/PanuonWindow.xaml
index e2f650f..a9ffe87 100644
--- a/WPFProject/PanuonWindow.xaml
+++ b/WPFProject/PanuonWindow.xaml
@@ -18,6 +18,7 @@
             xmlns:hc="clr-namespace:HMI.Core;assembly=HMI.Core"
             Closed="window_Closed"
             Topmost="False"
+            Title="TestPlatform"
             pu:WindowXCaption.Background="Transparent"
             pu:WindowXCaption.Height="80"
             IsOverlayerVisible="True"
diff --git a/WPFProject/WPFProject.csproj b/WPFProject/WPFProject.csproj
index 3fa1e7a..49262a9 100644
--- a/WPFProject/WPFProject.csproj
+++ b/WPFProject/WPFProject.csproj
@@ -125,8 +125,8 @@
     <Reference Include="Panuon.WPF, Version=1.1.2.2, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>packages\Panuon.WPF.1.1.3\lib\net472\Panuon.WPF.dll</HintPath>
     </Reference>
-    <Reference Include="Panuon.WPF.UI, Version=1.2.4.8, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>packages\Panuon.WPF.UI.1.2.4.9\lib\net472\Panuon.WPF.UI.dll</HintPath>
+    <Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
     </Reference>
     <Reference Include="PresentationFramework.Aero" />
     <Reference Include="System" />
@@ -494,6 +494,9 @@
     <Content Include="Lang\zh-CN\ServoManage.json">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </Content>
+    <Content Include="Lang\en-US\ServoManage.json">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
     <None Include="packages.config" />
     <None Include="Properties\app.manifest" />
     <None Include="Properties\Settings.settings">
diff --git a/WPFProject/WPFProject.sln b/WPFProject/WPFProject.sln
index d7f5c5a..cbbe457 100644
--- a/WPFProject/WPFProject.sln
+++ b/WPFProject/WPFProject.sln
@@ -41,6 +41,10 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.ServoManage", "..\Plugin.ServoManage\Plugin.ServoManage.csproj", "{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpcInterface", "..\..\HMI.Old\OPCInterface\OpcInterface\OpcInterface.csproj", "{E1464149-2C0A-499D-AB90-0C72E6ED1C53}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.DOControl", "..\Plugin.DOControl\Plugin.DOControl.csproj", "{306A83DC-A7DB-4057-BAA7-477D8756F5D9}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -201,6 +205,22 @@
 		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|Any CPU.Build.0 = Release|Any CPU
 		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|x64.ActiveCfg = Release|Any CPU
 		{1853E00F-6865-4BC6-974B-6A5E1C00BAFE}.Release|x64.Build.0 = Release|Any CPU
+		{E1464149-2C0A-499D-AB90-0C72E6ED1C53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E1464149-2C0A-499D-AB90-0C72E6ED1C53}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E1464149-2C0A-499D-AB90-0C72E6ED1C53}.Debug|x64.ActiveCfg = Debug|x64
+		{E1464149-2C0A-499D-AB90-0C72E6ED1C53}.Debug|x64.Build.0 = Debug|x64
+		{E1464149-2C0A-499D-AB90-0C72E6ED1C53}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E1464149-2C0A-499D-AB90-0C72E6ED1C53}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E1464149-2C0A-499D-AB90-0C72E6ED1C53}.Release|x64.ActiveCfg = Release|Any CPU
+		{E1464149-2C0A-499D-AB90-0C72E6ED1C53}.Release|x64.Build.0 = Release|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Debug|x64.Build.0 = Debug|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|x64.ActiveCfg = Release|Any CPU
+		{306A83DC-A7DB-4057-BAA7-477D8756F5D9}.Release|x64.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/WPFProject/packages.config b/WPFProject/packages.config
index 2260565..f5f1b25 100644
--- a/WPFProject/packages.config
+++ b/WPFProject/packages.config
@@ -7,7 +7,7 @@
   <package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.39" targetFramework="net472" />
   <package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
   <package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
-  <package id="Panuon.WPF.UI" version="1.2.4.9" targetFramework="net472" />
+  <package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
   <package id="System.IO" version="4.3.0" targetFramework="net472" />
   <package id="System.Net.Http" version="4.3.4" targetFramework="net472" />
   <package id="System.Runtime" version="4.3.0" targetFramework="net472" />

--
Gitblit v1.9.1