From 01c17e63a6d26085b6db1e188ea3bac3b9e26b30 Mon Sep 17 00:00:00 2001
From: tangxu <tangxu76880903>
Date: 星期三, 06 十一月 2024 09:30:41 +0800
Subject: [PATCH] 修改TreeView颜色

---
 WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockRegion.cs            |    2 
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeNodePara.cs             |   90 ++++
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.Designer.cs        |    2 
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage.cs                          |    7 
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.resx               |    2 
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage_StepInfo.cs                 |    2 
 WinFrmUI/DPumpHydr.WinFrmUI.RLT/Controls/TextBoxEdit/MaterialTextBoxEdit.cs |    4 
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.Designer.cs         |   20 
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeView.cs                 |  854 ++++++++++++++++++++++++++++++++++++++
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.resx                |   24 
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/GlobalResource.cs                        |    4 
 WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockGroup.cs             |   29 
 WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockPanel.cs             |    5 
 WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeNode.cs                 |  217 +++++++++
 14 files changed, 1,227 insertions(+), 35 deletions(-)

diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Controls/TextBoxEdit/MaterialTextBoxEdit.cs b/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Controls/TextBoxEdit/MaterialTextBoxEdit.cs
index 9233b5e..b02f86d 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Controls/TextBoxEdit/MaterialTextBoxEdit.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Controls/TextBoxEdit/MaterialTextBoxEdit.cs
@@ -1348,7 +1348,7 @@
                                     new(destRect.Width, 0),
                                     new(0, destRect.Height),
                         },
-                        destRect, GraphicsUnit.Pixel, grayImageAttributes);
+                        destRect, GraphicsUnit.Pixel);// 涓嶈鐏拌壊 , grayImageAttributes);
                 }
 
                 //Create a pre - processed copy of the image(RED)
@@ -1405,7 +1405,7 @@
                                     new(destRect.Width, 0),
                                     new(0, destRect.Height),
                         },
-                        destRect, GraphicsUnit.Pixel, grayImageAttributes);
+                        destRect, GraphicsUnit.Pixel);//, grayImageAttributes);
                 }
 
                 //Create a pre - processed copy of the image(RED)
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockGroup.cs b/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockGroup.cs
index eb27ecc..66b7dab 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockGroup.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockGroup.cs
@@ -705,7 +705,7 @@
         {
             Graphics g = e.Graphics;
 
-            using (SolidBrush b = new(ThemeProvider.Theme.Colors.GreyBackground))
+            using (SolidBrush b = new(System.Drawing.Color.White))//tangxu ThemeProvider.Theme.Colors.GreyBackground))
             {
                 g.FillRectangle(b, ClientRectangle);
             }
@@ -715,7 +715,7 @@
                 return;
             }
 
-            using (SolidBrush b = new(ThemeProvider.Theme.Colors.MediumBackground))
+            using (SolidBrush b = new(System.Drawing.Color.White))//tangxu ThemeProvider.Theme.Colors.MediumBackground))
             {
                 g.FillRectangle(b, _tabArea.ClientRectangle);
             }
@@ -736,7 +736,7 @@
             {
                 // Color divider
                 bool isActiveGroup = DockPanel.ActiveGroup == this;
-                Color divColor = isActiveGroup ? ThemeProvider.Theme.Colors.BlueSelection : ThemeProvider.Theme.Colors.GreySelection;
+                Color divColor = isActiveGroup ? ThemeProvider.Theme.Colors.BlueSelection : System.Drawing.Color.White;// ThemeProvider.Theme.Colors.GreySelection;
                 using (SolidBrush b = new(divColor))
                 {
                     Rectangle divRect = new(_tabArea.ClientRectangle.Left, _tabArea.ClientRectangle.Bottom - 2, _tabArea.ClientRectangle.Width, 2);
@@ -746,12 +746,12 @@
                 // Content dropdown list
                 Rectangle dropdownRect = new(_tabArea.DropdownRectangle.Left, _tabArea.DropdownRectangle.Top, _tabArea.DropdownRectangle.Width, _tabArea.DropdownRectangle.Height - 2);
 
-                using (SolidBrush b = new(ThemeProvider.Theme.Colors.MediumBackground))
+                using (SolidBrush b = new(System.Drawing.Color.White))//tangxu 绠ご鑳屾櫙鑹�  ThemeProvider.Theme.Colors.MediumBackground))
                 {
                     g.FillRectangle(b, dropdownRect);
                 }
 
-                using Bitmap img = Properties.Resources.arrow;
+                using Bitmap img = Properties.Resources.arrow;//绠ご鏄伆鑹�, 浠ュ悗鏀规垚鍒殑棰滆壊
                 g.DrawImageUnscaled(img, dropdownRect.Left + (dropdownRect.Width / 2) - (img.Width / 2), dropdownRect.Top + (dropdownRect.Height / 2) - (img.Height / 2) + 1);
             }
         }
@@ -763,18 +763,19 @@
             bool isVisibleTab = VisibleContent == tab.DockContent;
             bool isActiveGroup = DockPanel.ActiveGroup == this;
 
-            Color bgColor = isVisibleTab ? ThemeProvider.Theme.Colors.BlueSelection : ThemeProvider.Theme.Colors.DarkBackground;
+            Color bgColor =   isVisibleTab ? ThemeProvider.Theme.Colors.BlueSelection : System.Drawing.Color.White;// ThemeProvider.Theme.Colors.DarkBackground;
 
-            if (!isActiveGroup)
-            {
-                bgColor = isVisibleTab ? ThemeProvider.Theme.Colors.GreySelection : ThemeProvider.Theme.Colors.DarkBackground;
-            }
+            //if (!isActiveGroup)
+            //{
+            //    bgColor = isVisibleTab ? ThemeProvider.Theme.Colors.GreySelection : System.Drawing.Color.White;//ThemeProvider.Theme.Colors.DarkBackground;
+            //    //bgColor = isVisibleTab ? : ThemeProvider.Theme.Colors.DarkBackground;
+            //}
 
             if (tab.Hot && !isVisibleTab)
             {
-                bgColor = ThemeProvider.Theme.Colors.MediumBackground;
+                bgColor = System.Drawing.Color.Gray;// ThemeProvider.Theme.Colors.MediumBackground;
             }
-
+         
             using (SolidBrush b = new(bgColor))
             {
                 g.FillRectangle(b, tabRect);
@@ -840,10 +841,10 @@
             bool isVisibleTab = VisibleContent == tab.DockContent;
 
             Color bgColor = isVisibleTab ? ThemeProvider.Theme.Colors.GreyBackground : ThemeProvider.Theme.Colors.DarkBackground;
-
+            //System.Drawing.Color.White : System.Drawing.Color.Gray;//
             if (tab.Hot && !isVisibleTab)
             {
-                bgColor = ThemeProvider.Theme.Colors.MediumBackground;
+                bgColor = System.Drawing.Color.Gray;//ThemeProvider.Theme.Colors.MediumBackground;
             }
 
             using (SolidBrush b = new(bgColor))
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockPanel.cs b/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockPanel.cs
index 836eda4..8f7eef3 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockPanel.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockPanel.cs
@@ -118,7 +118,7 @@
             Regions = new Dictionary<DockArea, CrownDockRegion>();
             _contents = new List<CrownDockContent>();
 
-            BackColor = ThemeProvider.Theme.Colors.GreyBackground;
+            BackColor = System.Drawing.Color.White;// ThemeProvider.Theme.Colors.GreyBackground;
 
             CreateRegions();
         }
@@ -155,7 +155,7 @@
             CrownDockRegion region = Regions[dockContent.DockArea];
             if(dockContent.DockArea == DockArea.Right)
             {
-                region.Width = 290;
+                region.Width = RightDockWidth;
             }
           
             region.AddContent(dockContent, dockGroup);
@@ -164,6 +164,7 @@
 
             dockContent.Select();
         }
+        public int RightDockWidth { get; set; } = 310;
 
         public void InsertContent(CrownDockContent dockContent, CrownDockGroup dockGroup, DockInsertType insertType)
         {
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockRegion.cs b/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockRegion.cs
index f8c5e26..c01338e 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockRegion.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.RLT/Docking/Crown/CrownDockRegion.cs
@@ -403,7 +403,7 @@
             }
 
             // Fill body
-            using (SolidBrush b = new(ThemeProvider.Theme.Colors.GreyBackground))
+            using (SolidBrush b = new(ThemeProvider.Theme.Colors.GreyBackground))//System.Drawing.Color.White))//
             {
                 g.FillRectangle(b, ClientRectangle);
             }
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.Designer.cs b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.Designer.cs
index c02a4a1..8a3d5d7 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.Designer.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.Designer.cs
@@ -44,7 +44,7 @@
             // 
             // pictureBox1
             // 
-            pictureBox1.Image = Properties.Resources.WaitingGray32;
+            pictureBox1.Image = Properties.Resources.Need16;
             pictureBox1.Location = new System.Drawing.Point(19, 74);
             pictureBox1.Name = "pictureBox1";
             pictureBox1.Size = new System.Drawing.Size(100, 50);
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.resx b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.resx
index 99bf385..543ecb7 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.resx
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/DebugRLT/UserControl1.resx
@@ -125,7 +125,7 @@
         AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
         LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
         SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAqgIAAAJNU0Z0AUkBTAMBAQAB
-        SAEAAUgBAAEQAQABEAEABP8BIQEACP8BQgFNATYHAAE2AwABKAMAAUADAAEQAwABAQEAASAGAAEQEgAD
+        cAEAAXABAAEQAQABEAEABP8BIQEACP8BQgFNATYHAAE2AwABKAMAAUADAAEQAwABAQEAASAGAAEQEgAD
         UwGnA0YBgAM2AVcDAgEDBAADJgE5A0MBdgNEAXgDRAF4A0QBeQM0AVMDBgEI0AADRgGABAADIAEtA0YB
         fQNGAYADLQFGAwMBBAwAAx4BKgNGAX0DNwFazAADNgFXAyABLSgAAyYBOANFAXwEAcQAAwIBAwNGAX0s
         AAMgAS4DPgFqyAADRgGAMAADPgFqAxcBH8AAAyYBOQMtAUYwAAMHAQkDQwF3wAADQwF2AwMBBBAABAED
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/GlobalResource.cs b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/GlobalResource.cs
index 79a9868..109bca5 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/GlobalResource.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/GlobalResource.cs
@@ -22,7 +22,7 @@
             System.Drawing.Image image = null;
             if (tipTrailingIcon != null)
             {
-                image = GlobalResource.BuildImage(tipTrailingIcon);
+                image = Properties.Resources.TipRed22;//  GlobalResource.BuildImage(tipTrailingIcon);
             }
             return image;
         }
@@ -36,7 +36,7 @@
             System.Drawing.Image image = null;
             if (tipLeadingIcon != null)
             {
-                image = GlobalResource.BuildImage(tipLeadingIcon);
+                image = Properties.Resources.Need16;// GlobalResource.BuildImage(tipLeadingIcon);
             }
             return image;
         }
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage.cs b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage.cs
index faf0907..bcbc1c2 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage.cs
@@ -9,6 +9,7 @@
 using DPumpHydr.WinFrmUI.RLT.Native;
 using DPumpHydr.WinFrmUI.RLT.Docking.Crown;
 using DPumpHydr.WinFrmUI.Volute.TempCtrl;
+using static DPumpHydr.WinFrmUI.RLT.Helper.CrownHelper;
 
 namespace DPumpHydr.WinFrmUI.Volute
 {
@@ -34,9 +35,9 @@
 
 
 
-
-
-
+            ThemeProvider.Theme.Colors.HeaderBackground = Color.SteelBlue;
+            ThemeProvider.Theme.Colors.GreyBackground = Color.White;
+            //ThemeProvider.Theme.Colors.DarkBackground = Color.White;
 
         }
 
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage_StepInfo.cs b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage_StepInfo.cs
index e5993c7..b670788 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage_StepInfo.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/MainViewPage_StepInfo.cs
@@ -257,6 +257,8 @@
             if (step_id > this._stepTreeDockPanel.Step_ID_Section18_Grp &&
                 step_id <= this._stepTreeDockPanel.Step_ID_Section18_Grp + 8)
             {
+                if (_sectionBundleInfo == null)
+                    return;
                 if (_ctrlSectionShapeInfo18 == null)
                 {
                     _ctrlSectionShapeInfo18 = new ctrlSectionShapeInfo18();
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.Designer.cs b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.Designer.cs
index cbf3deb..d2b8da3 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.Designer.cs
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.Designer.cs
@@ -143,6 +143,16 @@
         /// <summary>
         ///   鏌ユ壘 System.Drawing.Bitmap 绫诲瀷鐨勬湰鍦板寲璧勬簮銆�
         /// </summary>
+        internal static System.Drawing.Bitmap Need16 {
+            get {
+                object obj = ResourceManager.GetObject("Need16", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   鏌ユ壘 System.Drawing.Bitmap 绫诲瀷鐨勬湰鍦板寲璧勬簮銆�
+        /// </summary>
         internal static System.Drawing.Bitmap properties_16xLG {
             get {
                 object obj = ResourceManager.GetObject("properties_16xLG", resourceCulture);
@@ -183,6 +193,16 @@
         /// <summary>
         ///   鏌ユ壘 System.Drawing.Bitmap 绫诲瀷鐨勬湰鍦板寲璧勬簮銆�
         /// </summary>
+        internal static System.Drawing.Bitmap TipRed22 {
+            get {
+                object obj = ResourceManager.GetObject("TipRed22", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   鏌ユ壘 System.Drawing.Bitmap 绫诲瀷鐨勬湰鍦板寲璧勬簮銆�
+        /// </summary>
         internal static System.Drawing.Bitmap WaitingGray32 {
             get {
                 object obj = ResourceManager.GetObject("WaitingGray32", resourceCulture);
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.resx b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.resx
index 588ca5a..9b4b5e8 100644
--- a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.resx
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/Properties/Resources.resx
@@ -121,11 +121,14 @@
   <data name="Files_7954" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\Files_7954.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
+  <data name="Console" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\Console.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="round_rotate_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\round_rotate_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
   <data name="Collection_16xLG" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\Collection_16xLG.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
-  </data>
-  <data name="Sect16" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>..\Resources\Sect16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
   <data name="finishstep16" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\finishstep16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
@@ -133,8 +136,11 @@
   <data name="xiangxia32" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\xiangxia32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
-  <data name="Console" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>..\Resources\Console.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  <data name="WaitingGray32" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\WaitingGray32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="Sect16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\Sect16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
   <data name="ingstep32" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\ingstep32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
@@ -154,10 +160,10 @@
   <data name="application_16x" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\application_16x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
-  <data name="round_rotate_16" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>..\Resources\round_rotate_16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  <data name="TipRed22" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\TipRed22.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
-  <data name="WaitingGray32" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>..\Resources\WaitingGray32.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  <data name="Need16" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\Need16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
 </root>
\ No newline at end of file
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeNode.cs b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeNode.cs
new file mode 100644
index 0000000..f1e0864
--- /dev/null
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeNode.cs
@@ -0,0 +1,217 @@
+锘�#region Imports
+
+using DPumpHydr.WinFrmUI.RLT.Util;
+using System;
+using System.Drawing;
+using static System.Net.Mime.MediaTypeNames;
+
+#endregion
+
+namespace DPumpHydr.WinFrmUI.Base
+{
+    #region StepTreeNode
+
+    public class StepTreeNode
+    {
+        public StepTreeNode(StepTreeView ParentTree, StepTreeNodePara paras)  
+        {
+            this.Nodes = new ObservableList<StepTreeNode>();
+            this.Text = paras.Caption;
+            this.NodePara = paras;
+            this._parentTree = ParentTree;
+        }
+ 
+
+ 
+
+        #region Event Region
+
+        public event EventHandler<ObservableListModified<StepTreeNode>> ItemsAdded;
+        public event EventHandler<ObservableListModified<StepTreeNode>> ItemsRemoved;
+
+        public event EventHandler TextChanged;
+        public event Action<StepTreeNode> NodeExpanded;
+        public event Action<StepTreeNode> NodeCollapsed;
+
+        #endregion
+
+        #region Field Region
+
+        private string _text;
+        private StepTreeView _parentTree;
+        private ObservableList<StepTreeNode> _nodes;
+
+        private bool _expanded;
+
+        #endregion
+
+        #region Property Region
+
+        public string Text
+        {
+            get => _text;
+            set
+            {
+                if (_text == value)
+                {
+                    return;
+                }
+
+                _text = value; 
+            }
+        }
+
+        public Rectangle ExpandArea { get; set; }
+
+        public Rectangle IconArea { get; set; }
+
+        public Rectangle TextArea { get; set; }
+
+        public Rectangle FullArea { get; set; }
+
+        public bool IsHover { get; set; } = false;
+
+        public System.Drawing.Image Icon { get; set; }
+
+
+        public bool Expanded
+        {
+            get => _expanded;
+            set
+            {
+                if (_expanded == value)
+                {
+                    return;
+                }
+
+                if (value == true && Nodes.Count == 0)
+                {
+                    return;
+                }
+
+                _expanded = value;
+
+                if (_expanded)
+                {
+                    NodeExpanded?.Invoke(this);
+                }
+                else
+                {
+                    NodeCollapsed?.Invoke(this);
+                }
+            }
+        }
+
+        public ObservableList<StepTreeNode> Nodes
+        {
+            get => _nodes;
+            set
+            { 
+                _nodes = value; 
+            }
+        }
+
+        public bool IsRoot { get; set; }
+
+        public StepTreeView ParentTree
+        {
+            get => _parentTree;
+            set
+            {
+                if (_parentTree == value)
+                {
+                    return;
+                }
+
+                _parentTree = value;
+
+                foreach (StepTreeNode node in Nodes)
+                {
+                    node.ParentTree = _parentTree;
+                }
+            }
+        }
+
+        public StepTreeNode ParentNode { get; set; }
+
+        public bool Odd { get; set; }
+
+        public object NodeType { get; set; }
+
+        public StepTreeNodePara NodePara { get; set; }
+
+        public string FullPath
+        {
+            get
+            {
+                StepTreeNode parent = ParentNode;
+                string path = Text;
+
+                while (parent != null)
+                {
+                    path = string.Format("{0}{1}{2}", parent.Text, "\\", path);
+                    parent = parent.ParentNode;
+                }
+
+                return path;
+            }
+        }
+
+        public StepTreeNode PrevVisibleNode { get; set; }
+
+        public StepTreeNode NextVisibleNode { get; set; }
+
+        public int VisibleIndex { get; set; }
+
+        public bool IsNodeAncestor(StepTreeNode node)
+        {
+            StepTreeNode parent = ParentNode;
+            while (parent != null)
+            {
+                if (parent == node)
+                {
+                    return true;
+                }
+
+                parent = parent.ParentNode;
+            }
+
+            return false;
+        }
+
+        #endregion
+
+ 
+
+        #region Method Region
+
+        //public void Remove()
+        //{
+        //    if (ParentNode != null)
+        //    {
+        //        ParentNode.Nodes.Remove(this);
+        //    }
+        //    else
+        //    {
+        //        ParentTree.Nodes.Remove(this);
+        //    }
+        //}
+
+        public void EnsureVisible()
+        {
+            StepTreeNode parent = ParentNode;
+
+            while (parent != null)
+            {
+                parent.Expanded = true;
+                parent = parent.ParentNode;
+            }
+        }
+
+        #endregion
+
+  
+    }
+
+    #endregion
+}
\ No newline at end of file
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeNodePara.cs b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeNodePara.cs
new file mode 100644
index 0000000..5ff1073
--- /dev/null
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeNodePara.cs
@@ -0,0 +1,90 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace DPumpHydr.WinFrmUI.Base
+{
+    /// <summary>
+    /// 姝ラ鏍戣妭鐐�
+    /// </summary>
+    public class StepTreeNodePara
+    {
+        /// <summary>
+        /// 鏁版嵁鐨勬湁鏁堟��
+        /// </summary>
+        public enum eDataState
+        {
+            閿欒 = 0,
+            姝g‘ = 1,
+            鏈煡 = 2
+        }
+
+        /// <summary>
+        /// 姝ラ杩涘害鐘舵��
+        /// </summary>
+        public enum eProgressState
+        {
+            鏈畬鎴� = 0,
+            姝e湪杩涜 = 1,
+            宸插畬鎴� = 2
+        }
+
+        /// <summary>
+        /// 鍞竴鏍囪瘑
+        /// </summary>
+        public long ID { get; set; }
+        /// <summary>
+        /// 鐖惰妭鐐笽D
+        /// </summary>
+        public long ParentID { get; set; }
+        /// <summary>
+        /// 鏄剧ず鏂囨湰
+        /// </summary>
+        public string Caption { get; set; }
+        /// <summary>
+        /// 姝ラ鍚�:涓嶅澶栨樉绀�
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 鏁版嵁鐨勬湁鏁堟��
+        /// </summary>
+        public eDataState DataState
+        {
+            get { return _dataState; }
+            set { _dataState = value; }
+        }
+        private eDataState _dataState = eDataState.姝g‘;
+        /// <summary>
+        /// 杩涘害鐘舵��
+        /// </summary>
+        public eProgressState ProgressState
+        {
+            get { return _progressState; }
+            set { _progressState = value; }
+        }
+        private eProgressState _progressState = eProgressState.鏈畬鎴�;
+
+        /// <summary>
+        /// 鏄惁鍙�塤濡傛灉璁剧疆涓篺alse鍒欏搴旇妭鐐逛笉鑳借仛鐒︼紙榛樿鏄疶RUE锛�
+        /// </summary>
+        public bool AllowSelect
+        {
+            get { return _allowSelect; }
+            set { _allowSelect = value; }
+        }
+        private bool _allowSelect = true;
+
+ 
+
+        /// <summary>
+        /// TAG
+        /// </summary>
+        public object Tag { get; set; }
+
+        /// <summary>
+        /// SpecImage
+        /// </summary>
+        public System.Drawing.Image SpecImage { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeView.cs b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeView.cs
new file mode 100644
index 0000000..1c1113c
--- /dev/null
+++ b/WinFrmUI/DPumpHydr.WinFrmUI.Volute/StepInfo/StepTreeView.cs
@@ -0,0 +1,854 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using DPumpHydr.WinFrmUI.RLT.Controls;
+using DPumpHydr.WinFrmUI.RLT.Util;
+using static DPumpHydr.WinFrmUI.RLT.Helper.CrownHelper;
+
+namespace DPumpHydr.WinFrmUI.Base
+{
+    public partial class StepTreeView : CrownScrollView
+    {
+        private StepTreeNode _selStepNode = null;
+        private StepTreeNodePara SelStepNodePara {
+            get
+            {
+                if (_selStepNode == null)
+                    return null;
+                return _selStepNode.NodePara;
+            }
+        }
+  
+        /// <summary>
+        /// 姝ラ鑺傜偣閫夋嫨鏀瑰彉鍓嶅悗浜嬩欢
+        /// </summary>
+        public event Func<StepTreeNodePara, StepTreeNodePara, bool> BeforeSelectedNodeChangedEvent;
+        public event Func<StepTreeNodePara, StepTreeNodePara, bool> AfterSelectedNodeChangedEvent;
+
+ 
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public StepTreeView()
+        {
+            BuildNodeImageList();
+
+
+
+            _nodes = new ObservableList<StepTreeNode>();
+ 
+
+
+        }
+
+        #region 鏋勫缓鍜岃幏鍙栨爲
+        /// <summary>
+        /// 鏍规嵁姝ラID鑱氱劍鑺傜偣
+        /// </summary>
+        /// <param name="StepNodeID"></param>
+        public void SetFocusedNode(long StepNodeID)
+        { 
+            this._selStepNode = GetNodeByID(StepNodeID);
+            RefreshAllNodesImage();
+            Invalidate();
+        }
+        /// <summary>
+        ///   鍐呴儴浣跨敤, 涓嶅澶�
+        /// </summary>
+        /// <param name="node"></param>
+        private void SetSelectNode4Click(StepTreeNode node)
+        {
+            if (node == null || !node.NodePara.AllowSelect)
+                return;
+
+ 
+            if (BeforeSelectedNodeChangedEvent != null)
+            {
+                if (BeforeSelectedNodeChangedEvent.Invoke(this.SelStepNodePara, node.NodePara) == false)
+                {
+                    return;
+                }
+            }
+
+            if (AfterSelectedNodeChangedEvent != null)
+            {
+                if (AfterSelectedNodeChangedEvent.Invoke(this.SelStepNodePara, node.NodePara) == false)
+                {
+                    return;
+                }
+            }
+            //
+            _selStepNode = node;
+  
+            RefreshAllNodesImage();
+
+            Invalidate();
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="StepNodeID"></param>
+        /// <returns></returns>
+        private StepTreeNode GetNodeByID(long StepNodeID)
+        { 
+            foreach (var node1 in this._nodes)
+            {
+                var step1 = node1.NodePara;
+                if (step1.ID == StepNodeID)
+                { 
+                    return node1;
+                }
+
+                if (node1.Nodes != null && node1.Nodes.Count > 0)
+                {
+                    foreach (var node2 in node1.Nodes)
+                    {
+                        var step2 = node2.NodePara;
+                        if (step2.ID == StepNodeID)
+                        {
+                            return node2;
+                        }
+
+                        if (node2.Nodes != null && node2.Nodes.Count > 0)
+                        {
+                            foreach (var node3 in node2.Nodes)
+                            {
+                                var step3 = node3.NodePara;
+                                if (step3.ID == StepNodeID)
+                                {
+                                    return node3;
+                                }
+                            }
+                        }
+
+                    }
+                }
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="node_paras_list"></param>
+        private void BuildTree(List<StepTreeNodePara> node_paras_list )
+        {
+            this._nodes.Clear();
+            var node_paras1 = node_paras_list.Where(x => x.ParentID == 0).OrderByDescending(x => x.ID);
+            foreach (var node_para1 in node_paras1)
+            {
+                StepTreeNode node1 = new(this,node_para1) ;
+  
+                var step_paras2 = node_paras_list.Where(x => x.ParentID == node_para1.ID).OrderBy(x => x.ID);
+                for (int x2 = 0; x2 < step_paras2.Count(); x2++)
+                {
+                    var step_para2 = step_paras2.ElementAt(x2);
+                    StepTreeNode node2 = new(this, step_para2);
+                    node1.Nodes.Add(node2);
+
+                    var step_paras3 = node_paras_list.Where(x => x.ParentID == step_para2.ID).OrderBy(x => x.ID);
+                    if (step_paras3 != null && step_paras3.Count() > 0)
+                    {
+                        for (int x3 = 0; x3 < step_paras3.Count(); x3++)
+                        {
+                            var step_para3 = step_paras3.ElementAt(x3);
+                            StepTreeNode node3 = new(this, step_para3);
+                            node2.Nodes.Add(node3);
+                        }
+                        node2.Expanded = true;
+                    }
+                }
+
+                node1.Expanded = true;
+
+                this._nodes.Add(node1);
+            }
+
+            UpdateNodes();
+        }
+
+ 
+        /// <summary>
+        /// 璁剧疆姝ラ鏁版嵁婧�
+        /// </summary>
+        /// <param name="value"></param>
+        public void SetStepSource(List<StepTreeNodePara> steps)
+        {
+            BuildTree(steps);
+            RefreshAllNodesImage();
+        }
+
+        /// <summary>
+        /// 璁剧疆姝ラ鏁版嵁婧�
+        /// </summary>
+        /// <param name="list"></param>
+        /// <param name="selStepNode"></param>
+        public void SetStepSource(List<StepTreeNodePara> steps, long ID)
+        {
+            BuildTree(steps);
+            SetFocusedNode(ID); 
+        }
+
+
+        #endregion
+
+ 
+
+        #region 鍥炬爣
+        public bool IsShowIcons { get; set; } = true;
+
+        private System.Windows.Forms.ImageList _imageList = null;
+        private void BuildNodeImageList()
+        {
+            _imageList = new System.Windows.Forms.ImageList();
+            _imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
+            _imageList.TransparentColor = System.Drawing.Color.Transparent;
+            _imageList.Images.Add(DPumpHydr.WinFrmUI.Volute.Properties.Resources.errorstep16);//0
+            _imageList.Images.Add(DPumpHydr.WinFrmUI.Volute.Properties.Resources.finishstep16);//1
+            _imageList.Images.Add(DPumpHydr.WinFrmUI.Volute.Properties.Resources.xiangxia32);//2
+            _imageList.Images.Add(DPumpHydr.WinFrmUI.Volute.Properties.Resources.ingstep32); //3
+            _imageList.Images.Add(DPumpHydr.WinFrmUI.Volute.Properties.Resources.WaitingGray32);//4
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="step_para"></param>
+        /// <returns></returns>
+        private void RefreshAllNodesImage()
+        {
+            foreach (var node1 in this._nodes)
+            {
+                node1.Icon = BuildNodeImage(node1.NodePara);
+
+                if (node1.Nodes != null)
+                {
+                    foreach (var node2 in node1.Nodes)
+                    {
+                        node2.Icon = BuildNodeImage(node2.NodePara);
+
+                        //鏈�澶氶亶鍘�3灞�
+                        if (node2.Nodes != null)
+                        {
+                            foreach (var node3 in node2.Nodes)
+                            {
+                                node3.Icon = BuildNodeImage(node3.NodePara);
+                            }
+                        }
+                    }
+                }
+
+            }
+
+
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="node"></param>
+        /// <returns></returns>
+        private System.Drawing.Image BuildNodeImage(StepTreeNodePara node)
+        {
+            if (node.SpecImage != null)
+                return node.SpecImage;
+            if (this._selStepNode != null && node.ID == this._selStepNode.NodePara.ID)
+            {
+                return this._imageList.Images[3];
+            }
+            if (node.ParentID == 0)
+                return this._imageList.Images[2];
+            if (node.DataState == StepTreeNodePara.eDataState.閿欒)
+                return this._imageList.Images[0];
+
+            if (node.ProgressState == StepTreeNodePara.eProgressState.宸插畬鎴�)
+                return this._imageList.Images[1];
+            if (node.ProgressState == StepTreeNodePara.eProgressState.鏈畬鎴�)
+                return this._imageList.Images[4];
+
+            if (node.ProgressState == StepTreeNodePara.eProgressState.姝e湪杩涜)
+                return this._imageList.Images[3];
+            return null;
+        }
+
+        //娉ㄥ唽浜嬩欢(澶囦唤)
+        private void RegistEvents()
+        { 
+            //this.treeList1.GetSelectImage += (sender, e) =>
+            //{
+            //    var ID = Convert.ToInt64(e.Node.GetValue("ID"));
+            //    var stepNode = GetStepSource().Find(x => x.ID == ID);
+            //    if (stepNode == null)
+            //        return;
+            //    switch (stepNode.DataState)
+            //    {
+            //        case TreeStepNode.eDataState.閿欒: e.NodeImageIndex = 0; break;
+            //        case TreeStepNode.eDataState.姝g‘: e.NodeImageIndex = 1; break;
+            //        case TreeStepNode.eDataState.鏈煡: e.NodeImageIndex = -1; break;
+            //        default: break;
+            //    }
+            //};
+
+            //this.treeList1.GetStateImage += (sender, e) =>
+            //{
+            //    var ID = Convert.ToInt64(e.Node.GetValue("ID"));
+            //    var stepNode = GetStepSource().Find(x => x.ID == ID);
+            //    if (stepNode == null)
+            //        return;
+            //    switch (stepNode.ProgressState)
+            //    {
+            //        case TreeStepNode.eProgressState.鏈畬鎴�: e.NodeImageIndex = 0; break;
+            //        case TreeStepNode.eProgressState.姝e湪杩涜: e.NodeImageIndex = 1; break;
+            //        case TreeStepNode.eProgressState.宸插畬鎴�: e.NodeImageIndex = 2; break;
+            //        default: break;
+            //    }
+            //};
+
+            //this.treeList1.BeforeFocusNode += (sender, e) =>
+            //{
+            //    var nextStepID = Convert.ToInt64(e.Node.GetValue("ID"));
+            //    var nextStepNode = GetStepSource().Find(x => x.ID == nextStepID);
+            //    if (!nextStepNode.AllowSelect)
+            //    {
+            //        e.CanFocus = false;
+            //        return;
+            //    }
+            //    if (_selStepNode != null)
+            //    {
+            //        if (_selStepNode.ID == nextStepNode.ID)
+            //            return;
+            //    }
+            //    if (this.BeforeStepNodeSelectedChangedEvent != null)
+            //    {
+            //        TreeStepNode beforeStepNode = null;
+            //        if (e.OldNode != null)
+            //        {
+            //            var beforeStepID = Convert.ToInt64(e.OldNode.GetValue("ID"));
+            //            beforeStepNode = GetStepSource().Find(x => x.ID == beforeStepID);
+            //        }
+            //        if (!this.BeforeStepNodeSelectedChangedEvent(beforeStepNode, nextStepNode))
+            //        {
+            //            e.CanFocus = false;
+            //            return;
+            //        }
+            //    }
+            //};
+
+            //this.treeList1.AfterFocusNode += (sender, e) =>
+            //{
+            //    var ID = Convert.ToInt64(e.Node.GetValue("ID"));
+            //    var nodeModel = GetStepSource().Find(x => x.ID == ID);
+            //    this.SelectedStepNode = nodeModel;
+            //};
+
+            //this.treeList1.AfterExpand += (sender, e) =>
+            //{
+            //    if (_selStepNode != null)
+            //    {
+            //        var node = this.treeList1.FindNodeByKeyID(_selStepNode.ID);
+            //        if (e.Node.Nodes.Contains(node))
+            //            this.treeList1.FocusedNode = node;
+            //    }
+            //};
+        }
+ 
+        #endregion
+
+
+
+        #region Field Region
+
+        private bool _disposed;
+
+        private readonly int _topNodeSpaceWidth = 5;//椤堕儴鑺傜偣宸﹁竟鐨勯棿闅旂┖闂�
+        private readonly int _iconSize = 16;
+
+        private int _itemHeight = 30;
+        private int _indent = 15;//缂╄繘 鐖惰妭鐐圭粰瀹氱殑姘村钩绌洪棿閲� Determines the amount of horizontal space given by parent node.
+
+
+
+
+        #endregion
+
+
+        #region 榧犳爣鎿嶄綔
+        protected override void OnMouseMove(MouseEventArgs e)
+        { 
+            CheckNodeHover();
+             
+            base.OnMouseMove(e);
+        }
+
+        protected override void OnMouseWheel(MouseEventArgs e)
+        {
+            CheckNodeHover();
+
+            base.OnMouseWheel(e);
+        }
+
+        protected override void OnMouseDown(MouseEventArgs e)
+        {
+            if (e.Button is MouseButtons.Left or MouseButtons.Right)
+            {
+                foreach (StepTreeNode node in _nodes)
+                {
+                    CheckNodeClick(node, OffsetMousePosition, e.Button);
+                }
+            }
+
+            base.OnMouseDown(e);
+        }
+
+        protected override void OnMouseClick(MouseEventArgs e)
+        {
+            base.OnMouseClick(e);
+        }
+
+        protected override void OnMouseDoubleClick(MouseEventArgs e)
+        {
+            if (ModifierKeys == Keys.Control)
+            {
+                return;
+            }
+
+            if (e.Button == MouseButtons.Left)
+            {
+                foreach (StepTreeNode node in _nodes)
+                {
+                    CheckNodeDoubleClick(node, OffsetMousePosition);
+                }
+            }
+
+            base.OnMouseDoubleClick(e);
+        }
+
+
+        protected override void OnMouseLeave(EventArgs e)
+        {
+            base.OnMouseLeave(e);
+
+            foreach (StepTreeNode node in _nodes)
+            {
+                NodeMouseLeave(node);
+            }
+        }
+
+
+
+        #endregion
+
+
+
+        #region 鏋勫缓Node
+
+        private ObservableList<StepTreeNode> _nodes;
+
+        private void UpdateNodes()
+        {
+            if (IsDragging)
+            {
+                return;
+            }
+
+            ContentSize = new(0, 0);
+
+            if (_nodes.Count == 0)
+            {
+                return;
+            }
+
+            int yOffset = 0;
+            bool isOdd = false;
+            int index = 0;
+            StepTreeNode prevNode = null;
+
+            for (int i = 0; i <= _nodes.Count - 1; i++)
+            {
+                StepTreeNode node = _nodes[i];
+                UpdateNode(node, ref prevNode, 0, ref yOffset, ref isOdd, ref index);
+            }
+
+            ContentSize = new(ContentSize.Width, yOffset);
+
+            Invalidate();
+        }
+
+        private void UpdateNode(StepTreeNode node, ref StepTreeNode prevNode, int indent, ref int yOffset,
+                                ref bool isOdd, ref int index)
+        {
+            UpdateNodeBounds(node, yOffset, indent);
+
+            yOffset += _itemHeight;
+
+            node.Odd = isOdd;
+            isOdd = !isOdd;
+
+            node.VisibleIndex = index;
+            index++;
+
+            node.PrevVisibleNode = prevNode;
+
+            if (prevNode != null)
+            {
+                prevNode.NextVisibleNode = node;
+            }
+
+            prevNode = node;
+
+            if (node.Expanded)
+            {
+                foreach (StepTreeNode childNode in node.Nodes)
+                {
+                    UpdateNode(childNode, ref prevNode, indent + _indent, ref yOffset, ref isOdd, ref index);
+                }
+            }
+        }
+
+        private void UpdateNodeBounds(StepTreeNode node, int yOffset, int indent)
+        {
+            int expandTop = yOffset + (_itemHeight / 2) - (_topNodeSpaceWidth / 2);
+            node.ExpandArea = new(indent + 3, expandTop, _topNodeSpaceWidth, _topNodeSpaceWidth);
+
+            int iconTop = yOffset + (_itemHeight / 2) - (_iconSize / 2);
+
+            if (IsShowIcons)
+            {
+                node.IconArea = new(node.ExpandArea.Right + 2, iconTop, _iconSize, _iconSize);
+            }
+            else
+            {
+                node.IconArea = new(node.ExpandArea.Right, iconTop, 0, 0);
+            }
+
+            using (Graphics g = CreateGraphics())
+            {
+                int textSize = (int)g.MeasureString(node.Text, Font).Width;
+                node.TextArea = new(node.IconArea.Right + 2, yOffset, textSize + 1, _itemHeight);
+            }
+
+            node.FullArea = new(indent, yOffset, node.TextArea.Right - indent, _itemHeight);
+
+            if (ContentSize.Width < node.TextArea.Right + 2)
+            {
+                ContentSize = new(node.TextArea.Right + 2, ContentSize.Height);
+            }
+        }
+
+        /// <summary>
+        /// 鑺傜偣鏄惁鎮仠
+        /// </summary>
+        private void CheckNodeHover()
+        {
+            if (!ClientRectangle.Contains(PointToClient(MousePosition)))
+            { 
+                return;
+            }
+
+            foreach (StepTreeNode node in _nodes)
+            {
+                CheckNodeHover(node, OffsetMousePosition);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="location"></param>
+        private void CheckNodeHover(StepTreeNode node, Point location)
+        {
+            bool isHover = node.FullArea.Contains(location);
+            if (node.IsHover != isHover)
+            {
+                node.IsHover = isHover;
+                Invalidate();
+            }
+
+            foreach (StepTreeNode childNode in node.Nodes)
+            {
+                CheckNodeHover(childNode, location);
+            }
+        }
+
+        /// <summary>
+        /// 榧犳爣绂诲紑
+        /// </summary>
+        /// <param name="node"></param>
+        private void NodeMouseLeave(StepTreeNode node)
+        {
+            node.IsHover = false;
+
+            foreach (StepTreeNode childNode in node.Nodes)
+            {
+                NodeMouseLeave(childNode);
+            }
+
+            Invalidate();
+        }
+
+
+        /// <summary>
+        /// 妫�鏌ラ紶鏍囩偣鍑诲湪鍝釜
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="location"></param>
+        /// <param name="button"></param>
+        private void CheckNodeClick(StepTreeNode node, Point location, MouseButtons button)
+        {
+            Rectangle rect = GetNodeFullRowArea(node);
+
+            if (rect.Contains(location))
+            {
+                if (node.ExpandArea.Contains(location))
+                {
+                    if (button == MouseButtons.Left)
+                    {
+                        node.Expanded = !node.Expanded;
+                    }
+                }
+                else
+                {
+                    if (button == MouseButtons.Left)
+                    {              
+                        SetSelectNode4Click(node); 
+                        return;
+                    }
+                    else if (button == MouseButtons.Right)
+                    {//浠ュ悗鍋氳彍鍗�
+                        //if (!SelectedNodes.Contains(node))
+                        //{
+                        //    SelectNode(node);
+                        //}
+
+                        return;
+                    }
+                }
+            }
+
+            //妫�鏌ヤ笅涓�绾�
+            if (node.Expanded)
+            {
+                foreach (StepTreeNode childNode in node.Nodes)
+                {
+                    CheckNodeClick(childNode, location, button);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 鍙屽嚮 灞曞紑
+        /// </summary>
+        /// <param name="node"></param>
+        /// <param name="location"></param>
+        private void CheckNodeDoubleClick(StepTreeNode node, Point location)
+        {
+            Rectangle rect = GetNodeFullRowArea(node);
+            if (rect.Contains(location))
+            {
+                if (!node.ExpandArea.Contains(location))
+                {
+                    node.Expanded = !node.Expanded;
+                }
+
+                return;
+            }
+
+            if (node.Expanded)
+            {
+                foreach (StepTreeNode childNode in node.Nodes)
+                {
+                    CheckNodeDoubleClick(childNode, location);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="node"></param>
+        /// <returns></returns>
+        public Rectangle GetNodeFullRowArea(StepTreeNode node)
+        {
+            if (node.ParentNode != null && !node.ParentNode.Expanded)
+            {
+                return new Rectangle(-1, -1, -1, -1);
+            }
+
+            int width = Math.Max(ContentSize.Width, Viewport.Width);
+            Rectangle rect = new(0, node.FullArea.Top, width, _itemHeight);
+            return rect;
+        }
+
+        /// <summary>
+        /// 纭繚鎵�閫夎妭鐐瑰彲瑙�
+        /// </summary>
+        public void EnsureVisible()
+        {
+            if (_selStepNode == null)
+            {
+                return;
+            }
+
+            // foreach (StepTreeNode node in SelectedNodes)
+            {
+                _selStepNode.EnsureVisible();
+            }
+
+            int itemTop = -1;
+
+            if (_selStepNode != null)
+            {
+                itemTop = _selStepNode.FullArea.Top;
+            }
+
+
+            int itemBottom = itemTop + _itemHeight;
+
+            if (itemTop < Viewport.Top)
+            {
+                VScrollTo(itemTop);
+            }
+
+            if (itemBottom > Viewport.Bottom)
+            {
+                VScrollTo(itemBottom - Viewport.Height);
+            }
+        }
+
+        #endregion
+
+
+        #region Paint Region
+
+        protected override void OnPaintBackground(PaintEventArgs e)
+        {
+            base.OnPaintBackground(e);
+            //LoadIcons();
+        }
+
+        protected override void PaintContent(Graphics g)
+        {
+            // Fill body
+            using (SolidBrush b = new(ThemeProvider.Theme.Colors.GreyBackground))
+            {
+                g.FillRectangle(b, ClientRectangle);
+            }
+
+            foreach (StepTreeNode node in _nodes)
+            {
+                DrawNode(node, g);
+            }
+        }
+        private System.Drawing.Color _oddRowBackgroundColor = System.Drawing.Color.White;
+        private System.Drawing.Color _evenRowBackgroundColor = System.Drawing.Color.FromArgb(238 ,233, 233);
+        private void DrawNode(StepTreeNode node, Graphics g)
+        {
+            Rectangle rect = GetNodeFullRowArea(node);
+
+            // 1.缁樺埗鑳屾櫙 Draw background
+            Color bgColor = node.Odd ? _oddRowBackgroundColor : _evenRowBackgroundColor;
+            if (_selStepNode != null && _selStepNode == node)
+            {//琚�変腑鐨勮儗鏅�
+                bgColor = ThemeProvider.Theme.Colors.BlueSelection;// Focused ? ThemeProvider.Theme.Colors.BlueSelection : System.Drawing.Color.DodgerBlue;
+            } 
+            using (SolidBrush b = new(bgColor))
+            {
+                g.FillRectangle(b, rect);
+            }
+
+
+            // 2.缁樺埗鍥炬爣 Draw icon
+            if (IsShowIcons && node.Icon != null)
+            {
+                g.DrawImageUnscaled(node.Icon, node.IconArea.Location);
+            }
+
+            // 3. 缁樺埗鏂囧瓧 Draw text
+            if (  node == this._selStepNode)
+            {
+                System.Drawing.Color text_color = System.Drawing.Color.White;
+                if (node.IsHover)
+                {
+                    text_color = ThemeProvider.Theme.Colors.BlueSelection;
+                }
+                using (SolidBrush b = new(text_color))
+                {
+                    StringFormat stringFormat = new()
+                    {
+                        Alignment = StringAlignment.Near,
+                        LineAlignment = StringAlignment.Center
+                    };
+
+                    g.DrawString(node.Text, Font, b, node.TextArea, stringFormat);
+                }
+            }
+            else
+            {
+                using (SolidBrush b = new(System.Drawing.Color.Black))
+                {
+                    StringFormat stringFormat = new()
+                    {
+                        Alignment = StringAlignment.Near,
+                        LineAlignment = StringAlignment.Center
+                    };
+
+                    g.DrawString(node.Text, Font, b, node.TextArea, stringFormat);
+                }
+            }
+
+
+            // 4. 缁樺埗涓嬩竴绾� Draw child nodes
+            if (node.Expanded)
+            {
+                foreach (StepTreeNode childNode in node.Nodes)
+                {
+                    DrawNode(childNode, g);
+                }
+            }
+        }
+
+        #endregion
+
+
+        #region Dispose Region
+
+        protected override void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            { 
+                if (BeforeSelectedNodeChangedEvent != null)
+                {
+                    BeforeSelectedNodeChangedEvent = null;
+                }
+                if (AfterSelectedNodeChangedEvent != null)
+                {
+                    AfterSelectedNodeChangedEvent = null;
+                }
+  
+                if (_nodes != null)
+                {
+                    _nodes.Dispose();
+                }
+                 
+                _disposed = true;
+            }
+
+            base.Dispose(disposing);
+        }
+
+        #endregion
+
+    }
+
+
+}

--
Gitblit v1.9.3