From 97e1e604737e70a9df2e83897d3bbf68292d0d72 Mon Sep 17 00:00:00 2001
From: Shuxia Ning <NingShuxia0927@outlook.com>
Date: 星期四, 19 十二月 2024 20:21:52 +0800
Subject: [PATCH] 代码修改

---
 WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.resx                      |  126 ++++++
 WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/AxisTitleHelper.cs                                                              |   31 +
 WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.en-US.resx                |  123 ++++++
 WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/Point2dListExtensions.cs                                                        |   27 +
 WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj.user                                                      |    3 
 WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/02-edit/UniversalEditChart.cs                                              |  101 +++--
 WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs                        |   84 ++++
 WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj                                                           |   10 
 WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs          |   11 
 WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.designer.cs               |  316 ++++++++++++++++
 WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/PhartExcelHelper.cs                                                             |  283 ++++++++++++++
 WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.Designer.cs |   16 
 12 files changed, 1,081 insertions(+), 50 deletions(-)

diff --git a/WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.Designer.cs b/WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.Designer.cs
index 47e7a09..1141a4e 100644
--- a/WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.Designer.cs
+++ b/WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.Designer.cs
@@ -28,17 +28,31 @@
         /// </summary>
         private void InitializeComponent()
         {
+            universalChartExcelImportCtrl1 = new Yw.WinFrmUI.Phart.UniversalChartExcelImportCtrl();
             SuspendLayout();
+            // 
+            // universalChartExcelImportCtrl1
+            // 
+            universalChartExcelImportCtrl1.Appearance.BackColor = SystemColors.Control;
+            universalChartExcelImportCtrl1.Appearance.Options.UseBackColor = true;
+            universalChartExcelImportCtrl1.Dock = DockStyle.Fill;
+            universalChartExcelImportCtrl1.Location = new Point(0, 0);
+            universalChartExcelImportCtrl1.Name = "universalChartExcelImportCtrl1";
+            universalChartExcelImportCtrl1.Size = new Size(912, 778);
+            universalChartExcelImportCtrl1.TabIndex = 0;
             // 
             // UniversalChartExcelImportCtrl
             // 
             AutoScaleDimensions = new SizeF(10F, 22F);
             AutoScaleMode = AutoScaleMode.Font;
+            Controls.Add(universalChartExcelImportCtrl1);
             Name = "UniversalChartExcelImportCtrl";
-            Size = new Size(843, 697);
+            Size = new Size(912, 778);
             ResumeLayout(false);
         }
 
         #endregion
+
+        private Yw.WinFrmUI.Phart.UniversalChartExcelImportCtrl universalChartExcelImportCtrl1;
     }
 }
diff --git a/WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs b/WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs
index d411017..2f37475 100644
--- a/WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs
+++ b/WinFrmUI/HStation.WinFrmUI.PhartRelation.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs
@@ -13,7 +13,14 @@
         /// </summary>  
         public void SetBindingData(string file_path, Yw.Ahart.eCurveType curve_type)
         {
+            var err_msg = Yw.WinFrmUI.PhartExcelHelper.ParseUniversalExcel(file_path, out List<Yw.Geometry.Point2d> list);
+            if (!string.IsNullOrEmpty(err_msg))
+            {
+                XtraMessageBox.Show(err_msg);
+                return;
+            }
 
+            this.universalChartExcelImportCtrl1.SetBindingData(curve_type, list);
         }
 
 
@@ -22,8 +29,8 @@
         /// </summary> 
         public Yw.Vmo.PhartDiagramExGraphListVmo Get()
         {
-            return new ();
-        } 
+            return new();
+        }
 
 
     }
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/AxisTitleHelper.cs b/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/AxisTitleHelper.cs
new file mode 100644
index 0000000..ec6f1f0
--- /dev/null
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/AxisTitleHelper.cs
@@ -0,0 +1,31 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yw.WinFrmUI
+{
+    public class AxisTitleHelper
+    {
+        public static (string AxisXTile, string AxisYTitle) Get(Yw.Ahart.eCurveType curve_type)
+        { 
+            switch (curve_type)
+            {
+                case Ahart.eCurveType.QH: return ("娴侀噺", "鎵▼");
+                case Ahart.eCurveType.QP: return ("娴侀噺", "鍔熺巼");
+                case Ahart.eCurveType.QE: return ("娴侀噺", "鏁堢巼");
+                case Ahart.eCurveType.QNPSH: return ("娴侀噺", "姘旇殌");
+                case Ahart.eCurveType.EqualE: break;
+                case Ahart.eCurveType.EqualP: break;
+                case Ahart.eCurveType.QL: return ("娴侀噺", "鍘嬪姏鎹熷け");
+                case Ahart.eCurveType.OL: return ("娴侀噺", "鎹熷け绯绘暟");
+                case Ahart.eCurveType.VOL: return ("姘翠綅", "姘撮噺");
+            }
+
+            return default;
+        } 
+     
+
+    }
+}
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/PhartExcelHelper.cs b/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/PhartExcelHelper.cs
new file mode 100644
index 0000000..b0843be
--- /dev/null
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/PhartExcelHelper.cs
@@ -0,0 +1,283 @@
+锘縰sing System.IO;
+
+namespace Yw.WinFrmUI
+{
+    public class PhartExcelHelper
+    {
+        #region Export
+
+        public static void ExportUniversalTemplate(string file_path, Yw.Ahart.eCurveType curve_type)
+        {
+            var title = AxisTitleHelper.Get(curve_type);
+            string col_x_title = title.AxisXTile;
+            string col_y_title = title.AxisYTitle;
+
+            NPOI.HSSF.UserModel.HSSFWorkbook theBook = new NPOI.HSSF.UserModel.HSSFWorkbook();
+            var theSheet1 = theBook.CreateSheet("Sheet1");
+
+            NPOI.SS.UserModel.IRow rowTile = theSheet1.CreateRow(0);
+            rowTile.CreateCell(0).SetCellValue(col_x_title);
+            rowTile.CreateCell(1).SetCellValue(col_y_title);
+
+
+            //寮哄埗Excel鍦ㄦ墦寮�鏃堕噸鏂拌绠楁墍鏈夊叕寮�
+            theSheet1.ForceFormulaRecalculation = true;
+            using FileStream fs = File.OpenWrite(file_path);
+            theBook.Write(fs);
+
+        }
+
+        public static void ExportPumpTemplate(string file_path)
+        {
+            NPOI.HSSF.UserModel.HSSFWorkbook theBook = new NPOI.HSSF.UserModel.HSSFWorkbook();
+            var theSheet1 = theBook.CreateSheet("Sheet1");
+
+            NPOI.SS.UserModel.IRow rowTile = theSheet1.CreateRow(0);
+            rowTile.CreateCell(0).SetCellValue("娴侀噺");
+            rowTile.CreateCell(1).SetCellValue("鎵▼");
+            rowTile.CreateCell(2).SetCellValue("鏁堢巼");
+            rowTile.CreateCell(3).SetCellValue("鍔熺巼");
+
+
+            theSheet1.ForceFormulaRecalculation = true;
+            using FileStream fs = File.OpenWrite(file_path);
+            theBook.Write(fs);
+
+        }
+
+        #endregion
+
+        #region Parse
+
+        public static string ParseUniversalExcel(string file_path, out List<Yw.Geometry.Point2d> list)
+        {
+            list = new  List<Geometry.Point2d>(); ;
+            if (!File.Exists(file_path))
+                return "鏂囦欢涓嶅瓨鍦�";
+
+            //鍒濆鍖栨枃浠�
+            NPOI.HSSF.UserModel.HSSFWorkbook theBook = null;
+            using (FileStream file = new FileStream(file_path, FileMode.Open, FileAccess.Read))
+            {
+                theBook = new NPOI.HSSF.UserModel.HSSFWorkbook(file);
+            }
+
+            //妫�鏌ヨ〃鏍兼槸鍚︾鍚�
+            NPOI.SS.UserModel.ISheet sheet1 = theBook.GetSheet("Sheet1");
+            if (sheet1 == null)
+            {
+                sheet1 = theBook.GetSheetAt(0);
+                if (sheet1 == null)
+                    return ("鏃燬heet鏁版嵁");
+            }
+
+            //鏍囬琛�
+            int title_line_index = 0;
+            //x 鍒�
+            int col_index_x = 1;
+            //y 鍒�
+            int col_index_y = 2;
+
+            var row_title = sheet1.GetRow(title_line_index);
+            if (row_title == null)
+            {
+                return ("绗竴琛岀涓�鍒椾笉鑳界┖");
+            }
+
+            //寮�濮嬭鍙栫殑琛�
+            int start_line = title_line_index + 1;
+            var cell_0 = row_title.GetCell(0);
+            if (cell_0 == null)
+            {
+                return ("鏃犳硶璇诲彇琛ㄥご鏂囦欢");
+            }
+            else if (cell_0.StringCellValue.Contains("搴忓彿"))
+            {
+                col_index_x = 1;
+                col_index_y = 2;
+            }
+            else if (cell_0.StringCellValue.Contains("娴侀噺"))
+            {
+                col_index_x = 0;
+                col_index_y = 1;
+            }
+
+            NPOI.SS.UserModel.IRow row_temp;
+            NPOI.SS.UserModel.ICell cell;
+
+            int line = 0;
+            for (line = start_line; line < 1000; line++)
+            {
+                row_temp = sheet1.GetRow(line);
+                if (row_temp == null)
+                    break;
+
+                cell = row_temp.GetCell(col_index_x);
+                if (cell == null)
+                    break;
+                if (!ParseCellValue(cell, out double x))
+                    break;
+
+                cell = row_temp.GetCell(col_index_y);
+                if (cell == null)
+                    break;
+                if (!ParseCellValue(cell, out double y))
+                    break;
+
+                list.Add(new(x, y));
+            }
+
+            return "";
+        }
+
+        public static List<(double Q, double H, double P, double E)> ParsePumpExcel(string fileName)
+        {
+            if (!File.Exists(fileName))
+                return default;
+            int line = 0;
+
+            //鍒濆鍖栨枃浠�
+            NPOI.HSSF.UserModel.HSSFWorkbook theBook = null;
+            using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
+            {
+                theBook = new NPOI.HSSF.UserModel.HSSFWorkbook(file);
+            }
+
+            //妫�鏌ヨ〃鏍兼槸鍚︾鍚�
+            NPOI.SS.UserModel.ISheet sheet1 = theBook.GetSheet("Sheet1");
+            if (sheet1 == null)
+            {
+                sheet1 = theBook.GetSheetAt(0);
+                if (sheet1 == null)
+                    throw new Exception("鏃燬heet鏁版嵁");
+            }
+
+            //鏍囬琛�
+            int title_line_index = 0;
+            //娴侀噺鍒�
+            int col_index_q = 1;
+            //鎵▼鍒�
+            int col_index_h = 2;
+            //鏁堢巼鍒�
+            int col_index_e = 3;
+            //鍔熺巼鍒�
+            int col_index_p = 4;
+
+            var row_title = sheet1.GetRow(title_line_index);
+            if (row_title == null)
+            {
+                throw new Exception("绗竴琛岀涓�鍒椾笉鑳界┖");
+            }
+
+            //寮�濮嬭鍙栫殑琛�
+            int start_line = title_line_index + 1;
+            var cell_0 = row_title.GetCell(0);
+            if (cell_0 == null)
+            {
+                throw new Exception("鏃犳硶璇诲彇琛ㄥご鏂囦欢");
+            }
+            else if (cell_0.StringCellValue.Contains("搴忓彿"))
+            {
+                col_index_q = 1;
+                col_index_h = 2;
+                col_index_e = 3;
+                col_index_p = 4;
+            }
+            else if (cell_0.StringCellValue.Contains("娴侀噺"))
+            {
+                col_index_q = 0;
+                col_index_h = 1;
+                col_index_e = 2;
+                col_index_p = 3;
+            }
+
+
+            NPOI.SS.UserModel.IRow row_temp = null;
+            NPOI.SS.UserModel.ICell cell;
+
+            var list = new List<(double Q, double H, double P, double E)>();
+            for (line = start_line; line < 1000; line++)
+            {
+
+                row_temp = sheet1.GetRow(line);
+                if (row_temp == null)
+                    break;
+
+                cell = row_temp.GetCell(col_index_q);
+                if (cell == null)
+                    break;
+                if (!ParseCellValue(cell, out double flow))
+                    break;
+                if (flow < 0)
+                    break;
+
+                cell = row_temp.GetCell(col_index_h);
+                if (cell == null)
+                    break;
+                if (!ParseCellValue(cell, out double head))
+                    break;
+                if (head < 0)
+                    break;
+
+                cell = row_temp.GetCell(col_index_e);
+                if (cell == null)
+                    break;
+                if (!ParseCellValue(cell, out double eff))
+                {
+                    eff = -1;
+                }
+
+
+                cell = row_temp.GetCell(col_index_p);
+                if (cell == null)
+                    break;
+                if (!ParseCellValue(cell, out double power))
+                {
+                    power = -1;
+                }
+
+                if (eff > 0)
+                {
+                    power = Yw.Pump.CalculationHelper.CalcuP(flow, head, eff);
+                }
+                else
+                {
+                    eff = Yw.Pump.CalculationHelper.CalcuE(flow, head, power);
+                }
+
+                if (eff > 99)
+                {
+                    throw new Exception("鏁堢巼澶т簬100%");
+                }
+
+                list.Add(new(flow, head, eff, power));
+
+            }
+
+            return list;
+        }
+
+        private static bool ParseCellValue(NPOI.SS.UserModel.ICell cell, out double cell_value)
+        {
+            cell_value = 0;
+            if (cell.CellType == NPOI.SS.UserModel.CellType.Numeric)
+            {
+                cell_value = cell.NumericCellValue;
+                return true;
+            }
+
+            if (cell.CellType == NPOI.SS.UserModel.CellType.String)
+            {
+                if (double.TryParse(cell.StringCellValue, out double value))
+                {
+                    cell_value = value;
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        #endregion
+    }
+}
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/Point2dListExtensions.cs b/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/Point2dListExtensions.cs
index 6e2783d..e3e2bc4 100644
--- a/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/Point2dListExtensions.cs
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/00-core/Point2dListExtensions.cs
@@ -105,7 +105,34 @@
             var cubic_spline = new Yw.Geometry.CubicSpline2d(pt_list);
             return cubic_spline.GetPointList(pt_list.Count);
         }
+        /// <summary>
+        /// 
+        /// </summary> 
+        public static List<Yw.Geometry.Point2d> GetFitPointList(this List<Yw.Geometry.Point2d> pt_list,Yw.Ahart.eFeatType feat_type)
+        {
+            if (pt_list == null || !pt_list.Any())
+                return default;
+            switch (feat_type)
+            {
+                case Ahart.eFeatType.Polynomial:
+                    {
+                        var cubic_spline = new Yw.Geometry.PolynomialSpline2d(pt_list);
+                        return cubic_spline.GetPointList(pt_list.Count);
+                    }
+                case Ahart.eFeatType.Cubic:
+                    {
+                        var cubic_spline = new Yw.Geometry.CubicSpline2d(pt_list);
+                        return cubic_spline.GetPointList(pt_list.Count);
+                    }
+                case Ahart.eFeatType.Through2d:
+                    {
+                        var cubic_spline = new Yw.Geometry.ThroughSpline2d(pt_list);
+                        return cubic_spline.GetPointList(pt_list.Count);
+                    }
+            }
 
+            return default; 
+        }
 
         /// <summary>
         /// 
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/02-edit/UniversalEditChart.cs b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/02-edit/UniversalEditChart.cs
index d4c7b94..7e579d1 100644
--- a/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/02-edit/UniversalEditChart.cs
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/02-edit/UniversalEditChart.cs
@@ -19,10 +19,12 @@
         private XYDiagram _diagram;
         private XYDiagramDefaultPane _default_pane;
         private AxisX _axis_x;
-        private AxisY _axis_y; 
+        private AxisY _axis_y;
 
         private List<Yw.Geometry.Point2d> _point_pt_list; 
         private List<Yw.Geometry.Point2d> _line_pt_list;
+
+        private Series _series_pt; 
 
         private UniversalCoordinate _coordinate;
         private bool _initial_data = false; 
@@ -113,19 +115,15 @@
 
             _diagram = (XYDiagram)chartControl1.Diagram;
             _default_pane=_diagram.DefaultPane;
-            _axis_x = _diagram.AxisX;
-            //_axis_x.SetAxisXQDisplay();
+            _axis_x = _diagram.AxisX; 
             _axis_y = _diagram.AxisY;
-            //_axis_y.SetAxisYQLDisplay();
-
-           
+   
 
             _axis_x.Visibility = DefaultBoolean.False;
             _axis_x.GridLines.Visible = false;
             _axis_y.Visibility = DefaultBoolean.False;
             _axis_y.GridLines.Visible = false;
-             
-
+              
             this.chartControl1.SetChartMonoColorDisplay();
         }
 
@@ -151,12 +149,32 @@
         /// <summary>
         /// 缁戝畾鏁版嵁
         /// </summary> 
+        public void Clear()
+        {
+            _initial_data = false;
+            _point_pt_list = null;
+            _line_pt_list = null;
+            _coordinate = null;
+            _series_pt = null;  
+
+            this.chartControl1.BeginInit();
+            this.chartControl1.Series.Clear();
+            this.chartControl1.AnnotationRepository.Clear();
+            this.chartControl1.Legend.CustomItems.Clear(); 
+            this.chartControl1.EndInit(); 
+        }
+
+
+        /// <summary>
+        /// 缁戝畾鏁版嵁
+        /// </summary> 
         public void SetBindingData(List<Yw.Geometry.Point2d> point_pt_list, List<Yw.Geometry.Point2d> line_pt_list, string coordinate = null, Color? color = null)
         {
             _initial_data = false;
             _point_pt_list = point_pt_list;
             _line_pt_list = line_pt_list;
             _coordinate = UniversalCoordinate.ToModel(coordinate);
+            _series_pt = null;
 
             this.chartControl1.BeginInit();
             this.chartControl1.Series.Clear();
@@ -168,16 +186,15 @@
                 this.chartControl1.EndInit();
                 return;
             }
-             
-            AddPointSeries(color.Value, _axis_x, _axis_y, _default_pane, _point_pt_list);
-            AddLineSeries(color.Value, _axis_x, _axis_y, _default_pane, _line_pt_list); 
+
+            _series_pt = AddPointSeries(color.Value, _axis_x, _axis_y, _default_pane, _point_pt_list);
+            AddLineSeries(color.Value, _axis_x, _axis_y, _default_pane, _line_pt_list);
             if (_coordinate == null)
                 SetCoordinate();
 
             SetChartAxis();
             this.chartControl1.EndInit();
             _initial_data = true;
-              
         }
 
         //鏄惁鏄棤鏁堟暟鎹�
@@ -193,15 +210,17 @@
             {
                 return true;
             }
+            if (_series_pt == null)
+                return true;
             return false;
         }
 
         #region Add Chart Data 
 
-        private void AddPointSeries(Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list)
+        private Series AddPointSeries(Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list)
         {
             if (pt_list == null || !pt_list.Any())
-                return;
+                return null;
 
             var view = new DevExpress.XtraCharts.PointSeriesView();
             view.PointMarkerOptions.Size = 8;
@@ -234,6 +253,8 @@
             series.CrosshairLabelPattern = "{A}";
             series.Points.AddRange(series_pt_list.ToArray());
             this.chartControl1.Series.Add(series);
+
+            return series;
         }
 
         private void AddLineSeries(Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list, DashStyle dash = DashStyle.Solid)
@@ -365,38 +386,37 @@
         #endregion Calc
 
         #region ChartEvent
-
-        private SeriesPoint _pick_point = null;// 閫変腑鐐� 
+         
+        private int _pick_point_index = -1;
         private void chartControl1_MouseDown(object sender, MouseEventArgs e)
         {
             if (!_initial_data)
                 return;
             var hitInfo = chartControl1.CalcHitInfo(e.Location);
-            _pick_point = null;
+            _pick_point_index = -1;
             if (e.Button == MouseButtons.Left)
             {
-                if (hitInfo.InSeriesPoint && hitInfo.SeriesPoint.Tag is int)
+                if (hitInfo.InSeriesPoint && hitInfo.SeriesPoint.Tag is int index)
                 {
-                    _pick_point = hitInfo.SeriesPoint;
+                    _pick_point_index = index;
                 }
             }
         }
-
 
         private void chartControl1_MouseMove(object sender, MouseEventArgs e)
         {
             if (!_mouse_mode)
                 return;
-            if (IsInvalidData())
+            if (_pick_point_index < 0)
                 return;
-            if (_pick_point == null)
+            if (IsInvalidData())
                 return;
             var diagram_coordinates = _diagram.PointToDiagram(e.Location);
             var axis_value = diagram_coordinates.GetAxisValue(_axis_y);
             if (axis_value == null)
                 return;
-            _pick_point.Values[0] = axis_value.NumericalValue;
-            _pick_point.NumericalArgument = diagram_coordinates.NumericalArgument;
+            _series_pt.Points[_pick_point_index].Values[0] = axis_value.NumericalValue;
+            _series_pt.Points[_pick_point_index].NumericalArgument = diagram_coordinates.NumericalArgument;
         }
 
 
@@ -404,32 +424,28 @@
         {
             if (!_mouse_mode)
                 return;
+            if (_pick_point_index < 0)
+                return;
             if (IsInvalidData())
-                return;
-            if (_pick_point == null)
-                return;
-            if (_pick_point.Tag is not int index)
-                return;
-            var x = _pick_point.NumericalArgument;
-            var y = _pick_point.Values[0];
-            SetPointPtValue(index, x, y);
-
-            _pick_point = null;
+                return; 
+            var x = _series_pt.Points[_pick_point_index].NumericalArgument;
+            var y = _series_pt.Points[_pick_point_index].Values[0];
+            SetPointValue(_pick_point_index, x, y);
+            _pick_point_index = -1;
         }
-
 
         private void chartControl1_KeyUp(object sender, KeyEventArgs e)
         {
-            if (!_initial_data)
+            if (_mouse_mode)
                 return;
-            if (_pick_point == null)
+            if (_pick_point_index < 0)
                 return;
             if (IsInvalidData())
                 return;
             double space_x = _coordinate.CoordSpaceX / 50;
             double space_y = _coordinate.CoordSpaceY / 50;
-            double x = _pick_point.NumericalArgument;
-            double y = _pick_point.Values[0];
+            double x = _series_pt.Points[_pick_point_index].NumericalArgument;
+            double y = _series_pt.Points[_pick_point_index].Values[0];
             if (e.KeyCode == Keys.Up)
             {
                 y += space_y;
@@ -446,17 +462,14 @@
             {
                 x += space_x;
             }
-            _pick_point.Values[0] = y;
-            _pick_point.NumericalArgument = x;
-            var index = _pick_point.Tag.is
-            SetPointPtValue();
+            SetPointValue(_pick_point_index, x, y);
         }
 
 
         /// <summary>
         /// 鏇存柊鏁版嵁
         /// </summary>
-        private void SetPointPtValue(int index, double x, double y)
+        private void SetPointValue(int index, double x, double y)
         {
             if (IsInvalidData())
                 return;
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs
new file mode 100644
index 0000000..6996047
--- /dev/null
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.cs
@@ -0,0 +1,84 @@
+锘縩amespace Yw.WinFrmUI.Phart
+{
+    public partial class UniversalChartExcelImportCtrl : DevExpress.XtraEditors.XtraUserControl
+    {
+        public UniversalChartExcelImportCtrl()
+        {
+            InitializeComponent();
+            this.gridView1.SetDefaultEditView();
+            this.gridView1.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
+
+            this.repImgCmbFeatType.Items.Add("涓夋鎷熷悎", Yw.Ahart.eFeatType.Cubic, -1);
+            this.repImgCmbFeatType.Items.Add("涓嶆嫙鍚�", Yw.Ahart.eFeatType.Through2d, -1);
+           
+        }
+
+         
+        private Yw.Ahart.eFeatType _feat_type;
+        private List<Yw.Geometry.Point2d> _def_pt_list = null;
+
+        /// <summary>
+        /// 缁戝畾鏁版嵁
+        /// </summary> 
+        public void SetBindingData(Yw.Ahart.eCurveType curve_type, List<Yw.Geometry.Point2d> def_pt_list)
+        { 
+            _def_pt_list = def_pt_list;
+            _def_pt_list ??= new List<Geometry.Point2d>();
+            _feat_type = Yw.Ahart.eFeatType.Cubic;
+
+            var (axis_x_title, axis_y_title) = AxisTitleHelper.Get(curve_type);
+            this.colX.Caption = axis_x_title;
+            this.colY.Caption = axis_x_title;
+
+            this.universalEditChart1.AxisXTitle = axis_x_title;
+            this.universalEditChart1.AxisYTitle = axis_y_title;
+
+            this.bindingSource1.DataSource = _def_pt_list;
+            this.bindingSource1.ResetBindings(false);
+             
+        }
+
+
+        //璁剧疆鍥捐〃
+        private void SetChart(Yw.Ahart.eFeatType feat_type, List<Yw.Geometry.Point2d> def_pt_list)
+        {
+            if (def_pt_list == null || def_pt_list.Count < 4)
+            {
+                this.universalEditChart1.Clear();
+                return;
+            }
+            var fit_pt_list = def_pt_list.GetFitPointList(feat_type);
+            this.universalEditChart1.SetBindingData(def_pt_list, fit_pt_list);
+        }
+         
+
+        //鍊煎彉鎹�
+        private void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
+        {
+            SetChart(_feat_type, _def_pt_list);
+        }
+
+        //鎷熷悎
+        private void barFeatType_EditValueChanged(object sender, EventArgs e)
+        {
+            _feat_type = (Yw.Ahart.eFeatType)this.barFeatType.EditValue;
+            SetChart(_feat_type, _def_pt_list);
+        }
+
+        /// <summary>
+        /// 鑾峰彇鏁版嵁
+        /// </summary> 
+        public bool Get(out Yw.Ahart.eFeatType feat_type, out List<Yw.Geometry.Point2d> pt_list)
+        {
+            feat_type = _feat_type;
+            pt_list = _def_pt_list;
+            if (_def_pt_list == null || !_def_pt_list.Any())
+                return false;
+            return true;
+        }
+
+
+     
+    }
+
+}
\ No newline at end of file
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.designer.cs b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.designer.cs
new file mode 100644
index 0000000..d878490
--- /dev/null
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.designer.cs
@@ -0,0 +1,316 @@
+锘縩amespace Yw.WinFrmUI.Phart
+{
+    partial class UniversalChartExcelImportCtrl
+    {
+        /// <summary> 
+        /// Requipuired designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary> 
+        /// Requipuired method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+            layoutControl1 = new DevExpress.XtraLayout.LayoutControl();
+            gridControl1 = new DevExpress.XtraGrid.GridControl();
+            bindingSource1 = new BindingSource(components);
+            gridView1 = new DevExpress.XtraGrid.Views.Grid.GridView();
+            colID = new DevExpress.XtraGrid.Columns.GridColumn();
+            colX = new DevExpress.XtraGrid.Columns.GridColumn();
+            colY = new DevExpress.XtraGrid.Columns.GridColumn();
+            Root = new DevExpress.XtraLayout.LayoutControlGroup();
+            layoutControlGroup1 = new DevExpress.XtraLayout.LayoutControlGroup();
+            layoutControlItem3 = new DevExpress.XtraLayout.LayoutControlItem();
+            universalEditChart1 = new UniversalEditChart();
+            sidePanel1 = new DevExpress.XtraEditors.SidePanel();
+            sidePanel2 = new DevExpress.XtraEditors.SidePanel();
+            barDockControlLeft = new DevExpress.XtraBars.BarDockControl();
+            barManager1 = new DevExpress.XtraBars.BarManager(components);
+            bar2 = new DevExpress.XtraBars.Bar();
+            barFeatType = new DevExpress.XtraBars.BarEditItem();
+            repImgCmbFeatType = new DevExpress.XtraEditors.Repository.RepositoryItemImageComboBox();
+            barDockControlTop = new DevExpress.XtraBars.BarDockControl();
+            barDockControlBottom = new DevExpress.XtraBars.BarDockControl();
+            barDockControlRight = new DevExpress.XtraBars.BarDockControl();
+            ((System.ComponentModel.ISupportInitialize)layoutControl1).BeginInit();
+            layoutControl1.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)gridControl1).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)bindingSource1).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)gridView1).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)Root).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)layoutControlGroup1).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)layoutControlItem3).BeginInit();
+            sidePanel1.SuspendLayout();
+            sidePanel2.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)barManager1).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)repImgCmbFeatType).BeginInit();
+            SuspendLayout();
+            // 
+            // layoutControl1
+            // 
+            layoutControl1.Controls.Add(gridControl1);
+            layoutControl1.Dock = DockStyle.Fill;
+            layoutControl1.Location = new Point(1, 0);
+            layoutControl1.Name = "layoutControl1";
+            layoutControl1.OptionsCustomizationForm.DesignTimeCustomizationFormPositionAndSize = new Rectangle(784, 368, 986, 935);
+            layoutControl1.Root = Root;
+            layoutControl1.Size = new Size(425, 660);
+            layoutControl1.TabIndex = 0;
+            layoutControl1.Text = "layoutControl1";
+            // 
+            // gridControl1
+            // 
+            gridControl1.DataSource = bindingSource1;
+            gridControl1.Location = new Point(0, 33);
+            gridControl1.MainView = gridView1;
+            gridControl1.Name = "gridControl1";
+            gridControl1.Size = new Size(425, 627);
+            gridControl1.TabIndex = 9;
+            gridControl1.ViewCollection.AddRange(new DevExpress.XtraGrid.Views.Base.BaseView[] { gridView1 });
+            // 
+            // gridView1
+            // 
+            gridView1.Columns.AddRange(new DevExpress.XtraGrid.Columns.GridColumn[] { colID, colX, colY });
+            gridView1.GridControl = gridControl1;
+            gridView1.Name = "gridView1";
+            gridView1.OptionsView.ShowDetailButtons = false;
+            gridView1.OptionsView.ShowGroupPanel = false;
+            gridView1.CellValueChanged += gridView1_CellValueChanged;
+            // 
+            // colID
+            // 
+            colID.FieldName = "ID";
+            colID.Name = "colID";
+            // 
+            // colX
+            // 
+            colX.AppearanceCell.Options.UseTextOptions = true;
+            colX.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
+            colX.AppearanceHeader.Options.UseTextOptions = true;
+            colX.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
+            colX.Caption = "X";
+            colX.FieldName = "X";
+            colX.Name = "colX";
+            colX.Visible = true;
+            colX.VisibleIndex = 0;
+            // 
+            // colY
+            // 
+            colY.AppearanceCell.Options.UseTextOptions = true;
+            colY.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
+            colY.AppearanceHeader.Options.UseTextOptions = true;
+            colY.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
+            colY.Caption = "Y";
+            colY.FieldName = "Y";
+            colY.Name = "colY";
+            colY.Visible = true;
+            colY.VisibleIndex = 1;
+            // 
+            // Root
+            // 
+            Root.EnableIndentsWithoutBorders = DevExpress.Utils.DefaultBoolean.True;
+            Root.GroupBordersVisible = false;
+            Root.Items.AddRange(new DevExpress.XtraLayout.BaseLayoutItem[] { layoutControlGroup1 });
+            Root.Name = "Root";
+            Root.Padding = new DevExpress.XtraLayout.Utils.Padding(0, 0, 0, 0);
+            Root.Size = new Size(425, 660);
+            Root.TextVisible = false;
+            // 
+            // layoutControlGroup1
+            // 
+            layoutControlGroup1.GroupStyle = DevExpress.Utils.GroupStyle.Title;
+            layoutControlGroup1.Items.AddRange(new DevExpress.XtraLayout.BaseLayoutItem[] { layoutControlItem3 });
+            layoutControlGroup1.Location = new Point(0, 0);
+            layoutControlGroup1.Name = "layoutControlGroup1";
+            layoutControlGroup1.Padding = new DevExpress.XtraLayout.Utils.Padding(0, 0, 0, 0);
+            layoutControlGroup1.Size = new Size(425, 660);
+            layoutControlGroup1.Spacing = new DevExpress.XtraLayout.Utils.Padding(0, 0, 0, 0);
+            layoutControlGroup1.Text = "瀹氫箟鐐�";
+            // 
+            // layoutControlItem3
+            // 
+            layoutControlItem3.Control = gridControl1;
+            layoutControlItem3.Location = new Point(0, 0);
+            layoutControlItem3.Name = "layoutControlItem3";
+            layoutControlItem3.Padding = new DevExpress.XtraLayout.Utils.Padding(0, 0, 0, 0);
+            layoutControlItem3.Size = new Size(425, 627);
+            layoutControlItem3.TextSize = new Size(0, 0);
+            layoutControlItem3.TextVisible = false;
+            // 
+            // universalEditChart1
+            // 
+            universalEditChart1.AxisXTitle = "Z";
+            universalEditChart1.AxisYTitle = "鎵▼/m";
+            universalEditChart1.Dock = DockStyle.Fill;
+            universalEditChart1.Location = new Point(0, 31);
+            universalEditChart1.MouseModel = false;
+            universalEditChart1.Name = "universalEditChart1";
+            universalEditChart1.Size = new Size(574, 629);
+            universalEditChart1.TabIndex = 3;
+            // 
+            // sidePanel1
+            // 
+            sidePanel1.Controls.Add(layoutControl1);
+            sidePanel1.Dock = DockStyle.Right;
+            sidePanel1.Location = new Point(574, 0);
+            sidePanel1.Name = "sidePanel1";
+            sidePanel1.Size = new Size(426, 660);
+            sidePanel1.TabIndex = 2;
+            sidePanel1.Text = "sidePanel1";
+            // 
+            // sidePanel2
+            // 
+            sidePanel2.Controls.Add(universalEditChart1);
+            sidePanel2.Controls.Add(barDockControlLeft);
+            sidePanel2.Controls.Add(barDockControlRight);
+            sidePanel2.Controls.Add(barDockControlBottom);
+            sidePanel2.Controls.Add(barDockControlTop);
+            sidePanel2.Dock = DockStyle.Fill;
+            sidePanel2.Location = new Point(0, 0);
+            sidePanel2.Name = "sidePanel2";
+            sidePanel2.Size = new Size(574, 660);
+            sidePanel2.TabIndex = 3;
+            sidePanel2.Text = "sidePanel2";
+            // 
+            // barDockControlLeft
+            // 
+            barDockControlLeft.CausesValidation = false;
+            barDockControlLeft.Dock = DockStyle.Left;
+            barDockControlLeft.Location = new Point(0, 31);
+            barDockControlLeft.Manager = barManager1;
+            barDockControlLeft.Size = new Size(0, 629);
+            // 
+            // barManager1
+            // 
+            barManager1.Bars.AddRange(new DevExpress.XtraBars.Bar[] { bar2 });
+            barManager1.DockControls.Add(barDockControlTop);
+            barManager1.DockControls.Add(barDockControlBottom);
+            barManager1.DockControls.Add(barDockControlLeft);
+            barManager1.DockControls.Add(barDockControlRight);
+            barManager1.Form = sidePanel2;
+            barManager1.Items.AddRange(new DevExpress.XtraBars.BarItem[] { barFeatType });
+            barManager1.MainMenu = bar2;
+            barManager1.MaxItemId = 1;
+            barManager1.RepositoryItems.AddRange(new DevExpress.XtraEditors.Repository.RepositoryItem[] { repImgCmbFeatType });
+            // 
+            // bar2
+            // 
+            bar2.BarName = "Main menu";
+            bar2.DockCol = 0;
+            bar2.DockRow = 0;
+            bar2.DockStyle = DevExpress.XtraBars.BarDockStyle.Top;
+            bar2.LinksPersistInfo.AddRange(new DevExpress.XtraBars.LinkPersistInfo[] { new DevExpress.XtraBars.LinkPersistInfo(barFeatType) });
+            bar2.OptionsBar.AllowQuickCustomization = false;
+            bar2.OptionsBar.DrawBorder = false;
+            bar2.OptionsBar.DrawDragBorder = false;
+            bar2.OptionsBar.UseWholeRow = true;
+            bar2.Text = "Main menu";
+            // 
+            // barFeatType
+            // 
+            barFeatType.Alignment = DevExpress.XtraBars.BarItemLinkAlignment.Right;
+            barFeatType.Caption = "鎷熷悎鏂瑰紡:";
+            barFeatType.Edit = repImgCmbFeatType;
+            barFeatType.EditWidth = 120;
+            barFeatType.Id = 0;
+            barFeatType.Name = "barFeatType";
+            barFeatType.PaintStyle = DevExpress.XtraBars.BarItemPaintStyle.CaptionGlyph;
+            barFeatType.EditValueChanged += barFeatType_EditValueChanged;
+            // 
+            // repImgCmbFeatType
+            // 
+            repImgCmbFeatType.AutoHeight = false;
+            repImgCmbFeatType.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] { new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo) });
+            repImgCmbFeatType.Name = "repImgCmbFeatType";
+            // 
+            // barDockControlTop
+            // 
+            barDockControlTop.CausesValidation = false;
+            barDockControlTop.Dock = DockStyle.Top;
+            barDockControlTop.Location = new Point(0, 0);
+            barDockControlTop.Manager = barManager1;
+            barDockControlTop.Size = new Size(574, 31);
+            // 
+            // barDockControlBottom
+            // 
+            barDockControlBottom.CausesValidation = false;
+            barDockControlBottom.Dock = DockStyle.Bottom;
+            barDockControlBottom.Location = new Point(0, 660);
+            barDockControlBottom.Manager = barManager1;
+            barDockControlBottom.Size = new Size(574, 0);
+            // 
+            // barDockControlRight
+            // 
+            barDockControlRight.CausesValidation = false;
+            barDockControlRight.Dock = DockStyle.Right;
+            barDockControlRight.Location = new Point(574, 31);
+            barDockControlRight.Manager = barManager1;
+            barDockControlRight.Size = new Size(0, 629);
+            // 
+            // UniversalChartExcelImportCtrl
+            // 
+            Appearance.BackColor = SystemColors.Control;
+            Appearance.Options.UseBackColor = true;
+            AutoScaleMode = AutoScaleMode.None;
+            Controls.Add(sidePanel2);
+            Controls.Add(sidePanel1);
+            Name = "UniversalChartExcelImportCtrl";
+            Size = new Size(1000, 660);
+            ((System.ComponentModel.ISupportInitialize)layoutControl1).EndInit();
+            layoutControl1.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)gridControl1).EndInit();
+            ((System.ComponentModel.ISupportInitialize)bindingSource1).EndInit();
+            ((System.ComponentModel.ISupportInitialize)gridView1).EndInit();
+            ((System.ComponentModel.ISupportInitialize)Root).EndInit();
+            ((System.ComponentModel.ISupportInitialize)layoutControlGroup1).EndInit();
+            ((System.ComponentModel.ISupportInitialize)layoutControlItem3).EndInit();
+            sidePanel1.ResumeLayout(false);
+            sidePanel2.ResumeLayout(false);
+            sidePanel2.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)barManager1).EndInit();
+            ((System.ComponentModel.ISupportInitialize)repImgCmbFeatType).EndInit();
+            ResumeLayout(false);
+        }
+
+        #endregion
+        private DevExpress.XtraLayout.LayoutControl layoutControl1;
+        private DevExpress.XtraLayout.LayoutControlGroup Root;
+        private System.Windows.Forms.BindingSource bindingSource1;
+        private DevExpress.XtraGrid.GridControl gridControl1;
+        private DevExpress.XtraGrid.Views.Grid.GridView gridView1;
+        private DevExpress.XtraGrid.Columns.GridColumn colID;
+        private DevExpress.XtraGrid.Columns.GridColumn colX;
+        private DevExpress.XtraGrid.Columns.GridColumn colY;
+        private DevExpress.XtraEditors.SidePanel sidePanel1;
+        private DevExpress.XtraLayout.LayoutControlItem layoutControlItem3;
+        private UniversalEditChart universalEditChart1;
+        private DevExpress.XtraEditors.SidePanel sidePanel2;
+        private DevExpress.XtraBars.BarDockControl barDockControlLeft;
+        private DevExpress.XtraBars.BarManager barManager1;
+        private DevExpress.XtraBars.Bar bar2;
+        private DevExpress.XtraBars.BarDockControl barDockControlTop;
+        private DevExpress.XtraBars.BarDockControl barDockControlBottom;
+        private DevExpress.XtraBars.BarDockControl barDockControlRight;
+        private DevExpress.XtraBars.BarEditItem barFeatType;
+        private DevExpress.XtraEditors.Repository.RepositoryItemImageComboBox repImgCmbFeatType;
+        private DevExpress.XtraLayout.LayoutControlGroup layoutControlGroup1;
+    }
+}
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.en-US.resx b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.en-US.resx
new file mode 100644
index 0000000..8463b00
--- /dev/null
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.en-US.resx
@@ -0,0 +1,123 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequipuence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequipuence>
+              <xsd:attribute name="name" use="requipuired" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequipuence>
+                <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:sequipuence>
+              <xsd:attribute name="name" type="xsd:string" use="requipuired" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequipuence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequipuence>
+              <xsd:attribute name="name" type="xsd:string" use="requipuired" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="btnUpdateCurve.Text" xml:space="preserve">
+    <value>Update Curve</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.resx b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.resx
new file mode 100644
index 0000000..7b3f44e
--- /dev/null
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/02-universal/03-import/01-excel/UniversalChartExcelImportCtrl.resx
@@ -0,0 +1,126 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="bindingSource1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>200, 17</value>
+  </metadata>
+  <metadata name="barManager1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
\ No newline at end of file
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj b/WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj
index 96482ca..ed7d23c 100644
--- a/WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj
@@ -58,11 +58,14 @@
     <Compile Remove="01-pump\01-single\03-variable-speed\PumpVariableSpeedViewModel.cs" />
     <Compile Remove="01-pump\01-single\04-run-view\PumpRunViewChart - 澶嶅埗.cs" />
     <Compile Remove="01-pump\01-single\04-run-view\PumpRunViewChart - 澶嶅埗.Designer.cs" />
+    <Compile Remove="02-universal\02-edit\UniversalEditCtrl.cs" />
+    <Compile Remove="02-universal\02-edit\UniversalEditCtrl.Designer.cs" />
     <Compile Remove="Title - 澶嶅埗.cs" />
   </ItemGroup>
 
   <ItemGroup>
     <EmbeddedResource Remove="01-pump\01-single\04-run-view\PumpRunViewChart - 澶嶅埗.resx" />
+    <EmbeddedResource Remove="02-universal\02-edit\UniversalEditCtrl.resx" />
   </ItemGroup>
 
   <ItemGroup>
@@ -115,6 +118,9 @@
     <Compile Update="02-universal\01-view\UniversalViewChart.cs">
       <SubType>UserControl</SubType>
     </Compile>
+    <Compile Update="02-universal\03-import\01-excel\UniversalChartExcelImportCtrl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
     <Compile Update="02-valve\01-view\ValveViewChart.cs">
       <SubType>UserControl</SubType>
     </Compile>
@@ -132,4 +138,8 @@
     </EmbeddedResource>
   </ItemGroup>
 
+  <ItemGroup>
+    <Folder Include="02-universal\03-import\02-image\" />
+  </ItemGroup>
+
 </Project>
diff --git a/WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj.user b/WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj.user
index a2eab3f..7f8fd37 100644
--- a/WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj.user
+++ b/WinFrmUI/Yw.WinFrmUI.Phart.Core/Yw.WinFrmUI.Phart.Core.csproj.user
@@ -26,9 +26,6 @@
     <Compile Update="02-universal\02-edit\UniversalEditChart.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Update="02-universal\02-edit\UniversalEditCtrl.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
     <Compile Update="02-valve\02-edit\ValveEditChart.cs">
       <SubType>UserControl</SubType>
     </Compile>

--
Gitblit v1.9.3