//项目文件刷新到窗口UI
            /// <summary>
            /// 在打开窗口时将主程序中的ProjectFile对象的信息反映到窗口的控件中
            /// </summary>
            /// <param name="FileContents"></param>
            /// <remarks></remarks>
            public void FileContentsToUI(clsData_FileContents FileContents)
            {
                if (FileContents != null)
                {
                    clsData_FileContents with_1 = FileContents;

                    //显示出项目中的工作簿
                    List <LstbxDisplayAndItem> listWkbks = new List <LstbxDisplayAndItem>();
                    foreach (Workbook wkbk in with_1.lstWkbks)
                    {
                        listWkbks.Add(new LstbxDisplayAndItem(wkbk.FullName, wkbk));
                    }
                    this.LstBxWorkbooks.DataSource = listWkbks;

                    //显示出项目文件中的施工进度工作表
                    List <LstbxDisplayAndItem> DataSource_SheetsProgressInProject = new List <LstbxDisplayAndItem>();
                    foreach (Worksheet shtProgress in with_1.lstSheets_Progress)
                    {
                        DataSource_SheetsProgressInProject.Add(new LstbxDisplayAndItem(DisplayedText: shtProgress.Name, Value:
                                                                                       shtProgress));
                    }
                    this.LstbxSheetsProgressInProject.DataSource = DataSource_SheetsProgressInProject;
                    //将数据源更新到所有的列表框
                    if (WorkBookInProjectChangedEvent != null)
                    {
                        WorkBookInProjectChangedEvent(null, FileContents, false);
                    }
                }
            }
            /// <summary>
            /// 窗口加载
            /// </summary>
            public void frmProjectContents_Load(object sender, EventArgs e)
            {
                //这一步的New非常重要,因为在每一次编辑完成后都会将其传址给主程序。
                F_NewFileContents = new clsData_FileContents();
                //
                APPLICATION_MAINFORM.MainForm.AllowDrop = false;
                clsProjectFile GlobalProjectfile = GlbApp.ProjectFile;

                if (GlobalProjectfile != null)
                {
                    this.F_OldFileContents = GlobalProjectfile.Contents;
                    FileContentsToUI(this.F_OldFileContents);
                    //在Label中更新此项目文件的绝对路径
                    this.LabelProjectFilePath.Text = GlobalProjectfile.FilePath;
                }

                //
                this.BindProperty();

                //根据不同的窗口状态设置窗口的样式
                switch (this.P_ProjectState)
                {
                case Miscellaneous.ProjectState.NewProject:
                    frmProjectFile with_1 = this;
                    with_1.Text = "New Project";
                    break;

                case Miscellaneous.ProjectState.EditProject:
                    //将项目文件中的内容更新的窗口中
                    frmProjectFile with_2 = this;
                    with_2.Text = "Edit Project";
                    break;
                }
            }
 private void RefreshDataBase(clsData_FileContents FileContents)
 {
     GlbApp.ProjectFile.Contents = FileContents;
     if (this.ProjectState == Miscellaneous.ProjectState.NewProject)
     {
         GlbApp.ProjectFile.FilePath = null;
     }
     GlbApp.DataBase = new ClsData_DataBase(FileContents);
     //将主程序的界面刷新为打开了文件后的界面
     APPLICATION_MAINFORM.MainForm.MainUI_ProjectOpened();
 }
            //项目中的数据库工作簿发生变化时的事件——窗口控件中列表框的刷新
            /// <summary>
            /// 项目中的数据库工作簿发生变化时的事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="clearListBox_Progress">是否要清空项目文件中的施工进度列表框中的内容</param>
            /// <remarks></remarks>
            public void _WorkBookInProjectChanged(object Sender, clsData_FileContents FileContents,
                                                  bool clearListBox_Progress)
            {
                //' 整个项目文件中所有的工作簿中的所有工作表的集合,用来作为列表控件中DataSource。
                List <LstbxDisplayAndItem> lstAllWorksheets = new List <LstbxDisplayAndItem>();

                //下面这一项“无”很重要,因为当数据库中对于某一个项目(如开挖剖面,测点坐标),
                //如果没有相应的数据,就应该选择“无”。
                lstAllWorksheets.Add(new LstbxDisplayAndItem(" 无", LstbxDisplayAndItem.NothingInListBox.None));

                //
                this.CmbbxProgressWkbk.Items.Clear();
                //
                foreach (LstbxDisplayAndItem lstItem in (this.LstBxWorkbooks.DataSource as List <LstbxDisplayAndItem>))
                {
                    Workbook wkbk = (Workbook)lstItem.Value;

                    //更新项目中的工作簿的组合框列表
                    this.CmbbxProgressWkbk.Items.Add(new LstbxDisplayAndItem(wkbk.Name, wkbk));

                    //提取工作簿中的所有工作表
                    foreach (Worksheet sht in wkbk.Worksheets)
                    {
                        lstAllWorksheets.Add(new LstbxDisplayAndItem(DisplayedText: wkbk.Name + " : " + sht.Name, Value:
                                                                     sht));
                    }
                }

                //更新: 将数据源更新到所有的列表框
                ListControlRefresh(lstAllWorksheets, FileContents);

                if (clearListBox_Progress)
                {
                    // 项目文件中的施工进度工作表的列表框的刷新
                    //这里应该判断项目文件中保存的施工进度工作表中,有哪些是位于被删除的那个工作簿的,然后将属于那个工作簿的工作表进行移除。
                    //现在为了简单起见,先直接将其清空。
                    this.LstbxSheetsProgressInProject.DataSource = null;
                    //.Items.Clear()
                    //.DisplayMember = LstbxDisplayAndItem.DisplayMember
                }
            }
            /// <summary>
            /// 项目中的数据库工作簿发生变化时,更新窗口中的相关列表框中的数据对象
            /// </summary>
            /// <param name="lstAllsheet"></param>
            /// <param name="FileContents"></param>
            /// <remarks></remarks>
            private void ListControlRefresh(List <LstbxDisplayAndItem> lstAllsheet,
                                            clsData_FileContents FileContents)
            {
                short intSheetsCount = System.Convert.ToInt16(lstAllsheet.Count);

                LstbxDisplayAndItem[] arrAllSheets1 = new LstbxDisplayAndItem[intSheetsCount - 1 + 1];
                LstbxDisplayAndItem[] arrAllSheets2 = new LstbxDisplayAndItem[intSheetsCount - 1 + 1];
                LstbxDisplayAndItem[] arrAllSheets3 = new LstbxDisplayAndItem[intSheetsCount - 1 + 1];
                LstbxDisplayAndItem[] arrAllSheets4 = new LstbxDisplayAndItem[intSheetsCount - 1 + 1];
                //这里一定要生成副本,因为如果是同一个引用变量,那么设置到三个控件的DataSource属性中后,
                //如果一个列表组合框的选择项发生变化,那个另外两个控件的选择项也会同步变化。
                arrAllSheets1 = lstAllsheet.ToArray() as LstbxDisplayAndItem[];
                arrAllSheets2 = arrAllSheets1.Clone() as LstbxDisplayAndItem[];
                arrAllSheets3 = arrAllSheets1.Clone() as LstbxDisplayAndItem[];
                arrAllSheets4 = arrAllSheets1.Clone() as LstbxDisplayAndItem[];

                //设置各种列表框中的数据以及选择的项lstbxWorksheetsInProjectFileChanged
                frmProjectFile with_1 = this;

                //开挖平面工作表
                CmbbxPlan.DataSource  = arrAllSheets1;
                CmbbxPlan.ValueMember = cstValueMember;
                if (FileContents.Sheet_PlanView != null)
                {
                    this.SheetToComboBox(CmbbxPlan, FileContents.Sheet_PlanView);
                }
                else
                {
                    CmbbxPlan.SelectedValue = LstbxDisplayAndItem.NothingInListBox.None;
                }

                //测点坐标工作表
                CmbbxPointCoordinates.DataSource  = arrAllSheets2;
                CmbbxPointCoordinates.ValueMember = cstValueMember;
                if (FileContents.Sheet_PointCoordinates != null)
                {
                    this.SheetToComboBox(CmbbxPointCoordinates, FileContents.Sheet_PointCoordinates);
                }
                else
                {
                    CmbbxPointCoordinates.SelectedValue = LstbxDisplayAndItem.NothingInListBox.None;
                }

                //开挖剖面工作表
                CmbbxSectional.DataSource  = arrAllSheets3;
                CmbbxSectional.ValueMember = cstValueMember;
                if (FileContents.Sheet_Elevation != null)
                {
                    this.SheetToComboBox(CmbbxSectional, FileContents.Sheet_Elevation);
                }
                else
                {
                    CmbbxSectional.SelectedValue = LstbxDisplayAndItem.NothingInListBox.None;
                }

                //开挖工况工作表
                CmbbxWorkingStage.DataSource  = arrAllSheets4;
                CmbbxWorkingStage.ValueMember = cstValueMember;
                if (FileContents.Sheet_WorkingStage != null)
                {
                    this.SheetToComboBox(CmbbxWorkingStage, FileContents.Sheet_WorkingStage);
                }
                else
                {
                    CmbbxWorkingStage.SelectedValue = LstbxDisplayAndItem.NothingInListBox.None;
                }


                //为施工进度列表服务的组合列表框
                if (CmbbxProgressWkbk.Items.Count == 0)
                {
                    //工作簿中的工作表列表框
                    this.LstbxSheetsProgressInWkbk.DataSource = null;
                    //上面将DataSource设置为Nothing会清空DisplayMember属性的值,那么下次再向列表框中添加成员时,
                    //其DisplayMember就为Nothing了,所以必须在下面设置好其DisplayMember的值。
                    this.LstbxSheetsProgressInWkbk.DisplayMember = LstbxDisplayAndItem.DisplayMember;
                }
                else
                {
                    CmbbxProgressWkbk.SelectedIndex = 0;
                }
            }
            /// <summary>
            /// 检测工作表节点的有效性,此类节点中包含了两个子节点,一个是此工作表所在的工作簿的路径,一个是此工作表的名称;
            /// 如果检测通过,则返回此Worksheet对象,否则返回Nothing
            /// </summary>
            /// <param name="WorksheetNode"></param>
            /// <param name="FileContents">用来放置项目文件中记录的工作簿或者工作表对象的变量</param>
            /// <param name="blnNodeForWorksheetValidated"></param>
            /// <returns>要返回的工作表对象,如果验证不通过,则返回Nothing</returns>
            /// <remarks></remarks>
            private Worksheet ValidateNodeForWorksheet(XmlElement WorksheetNode, clsData_FileContents FileContents, ref bool blnNodeForWorksheetValidated)
            {
                //要返回的工作表对象,如果验证不通过,则返回Nothing
                Worksheet ValidSheet = null;

                //
                blnNodeForWorksheetValidated = false;
                //节点中记录的工作簿路径
                string  strWkbkPath = "";
                XmlNode ndWkbkPath  = WorksheetNode.SelectSingleNode(DataBasePath.Nd3_FilePath);

                if (ndWkbkPath == null)                 //说明此节点中没有记录工作表所在的工作簿信息,也就是说,此节点中没有记录值
                {
                    return(ValidSheet);
                }
                else
                {
                    strWkbkPath = ndWkbkPath.InnerText;
                }

                //节点中记录的工作表名称
                string  strSheetName = "";
                XmlNode ndShetName   = WorksheetNode[DataBasePath.Nd3_SheetName];

                if (ndShetName == null)
                {
                    return(ValidSheet);
                }
                else
                {
                    strSheetName = ndShetName.InnerText;
                }


                //---先检测工作表所在的工作簿是否在有效的并成功打开和返回的工作簿列表中
                Workbook ValidWkbk = null;

                foreach (Workbook Wkbk in FileContents.lstWkbks)
                {
                    if (string.Compare(strWkbkPath, Wkbk.FullName, true) == 0)
                    {
                        ValidWkbk = Wkbk;
                        break;
                    }
                }

                //---- 根据工作簿的有效性与否执行相应的操作
                if (ValidWkbk != null)                 //说明工作簿有效
                {
                    //开始检测工作表的有效性

                    ValidSheet = ExcelFunction.MatchWorksheet(ValidWkbk, strSheetName);
                    if (ValidSheet != null)
                    {
                        blnNodeForWorksheetValidated = true;
                        //
                    }
                    else                     //此工作簿不存在,或者是没有成功赋值
                    {
                        this.F_blnFileValid = false;
                        this.F_lstErrorMessage.Add("The Specified Worksheet" + strSheetName + "is not found in workbook: " + strWkbkPath);
                    }
                }
                else                 //说明节点中记录的工作簿无效
                {
                    this.F_blnFileValid = false;
                    this.F_lstErrorMessage.Add("The Specified Workbook for worksheet " + strSheetName + " is not found : " + strWkbkPath);
                }

                //返回检测结果
                return(ValidSheet);
            }
            //从XML文件读取并检测文件中的成员是否存在
            /// <summary>
            /// 从项目文件中读取数据,并打开相应的Excel程序与工作簿
            /// </summary>
            /// <remarks></remarks>
            public void LoadFromXmlFile()
            {
                //载入文档
                XmlDocument xmlDoc = new XmlDocument();

                xmlDoc.Load(this.P_FilePath);
                //
                clsData_FileContents FC = new clsData_FileContents();
                XMLNode eleRoot         = xmlDoc.SelectSingleNode(System.Convert.ToString(My.Settings.Default.ProjectName));
                //这里可以尝试用GetElementById
                XmlElement Node_DataBase = eleRoot.SelectSingleNode(DataBasePath.Nd1_DataBasePaths);

                if (Node_DataBase == null)
                {
                    return;
                }
                // ---------------------- 读取文档 ------------------------
                // ---------------------- 读取文档 ------------------------

                XmlNodeList eleWkbks = Node_DataBase.GetElementsByTagName(DataBasePath.Nd2_WorkbooksInProject);

                foreach (XmlElement eleWkbk in eleWkbks)
                {
                    string   strWkbkPath = eleWkbk.InnerText;
                    Workbook wkbk        = ExcelFunction.MatchOpenedWkbk(wkbkPath: ref strWkbkPath, Application: ref this.F_Application, OpenIfNotOpened: true);
                    if (wkbk != null)
                    {
                        FC.lstWkbks.Add(wkbk);
                    }
                    else                     //此工作簿不存在,或者是没有成功赋值
                    {
                        this.F_blnFileValid = false;
                        this.F_lstErrorMessage.Add("The Specified Workbook is not found : " + strWkbkPath);
                    }
                }

                // ---------------- 施工进度工作表
                bool        blnNodeForWorksheetValidated = false;
                XmlNodeList eleSheetsProgress            = Node_DataBase.GetElementsByTagName(DataBasePath.Nd2_Progress);

                foreach (XmlElement eleSheetProgress in eleSheetsProgress)
                {
                    Worksheet shtProgress = ValidateNodeForWorksheet(eleSheetProgress, FC, ref blnNodeForWorksheetValidated);
                    if (blnNodeForWorksheetValidated)
                    {
                        FC.lstSheets_Progress.Add(shtProgress);
                    }
                }

                // ---------------- 开挖平面图工作表

                XmlNodeList eleSheetPlanView = Node_DataBase.GetElementsByTagName(DataBasePath.Nd2_PlanView);
                var         shtPlanView      = ValidateNodeForWorksheet((System.Xml.XmlElement)(eleSheetPlanView.Item(0)), FC, ref blnNodeForWorksheetValidated);

                FC.Sheet_PlanView = shtPlanView;

                // ---------------- 开挖剖面图工作表

                XmlNodeList eleSheetSectionalView = Node_DataBase.GetElementsByTagName(DataBasePath.Nd2_SectionalView);
                Worksheet   shtSectionalView      = ValidateNodeForWorksheet((System.Xml.XmlElement)(eleSheetSectionalView.Item(0)), FC, ref blnNodeForWorksheetValidated);

                FC.Sheet_Elevation = shtSectionalView;

                // ---------------- 测点坐标工作表

                XmlNodeList eleSheetPointCoordinates = Node_DataBase.GetElementsByTagName(DataBasePath.Nd2_PointCoordinates);
                Worksheet   shtPoint = ValidateNodeForWorksheet((System.Xml.XmlElement)(eleSheetPointCoordinates.Item(0)), FC, ref blnNodeForWorksheetValidated);

                FC.Sheet_PointCoordinates = shtPoint;

                // ---------------- 开挖工况工作表

                XmlNodeList eleWorkingStage = Node_DataBase.GetElementsByTagName(DataBasePath.Nd2_WorkingStage);
                Worksheet   shtWorkingStage = ValidateNodeForWorksheet((System.Xml.XmlElement)(eleWorkingStage.Item(0)), FC, ref blnNodeForWorksheetValidated);

                FC.Sheet_WorkingStage = shtWorkingStage;
                //
                this.P_FileContents = FC;
                //刷新主程序界面显示
                APPLICATION_MAINFORM.MainForm.MainUI_ProjectOpened();
            }
            //将项目中的内容写入XML文档
            /// <summary>
            /// 将设置好的项目写入文件
            /// </summary>
            /// <remarks></remarks>
            public void SaveToXmlFile()
            {
                clsData_FileContents FileContents = this.P_FileContents;
                XmlDocument          xmlDoc       = new XmlDocument();
                Worksheet            sheet        = default(Worksheet);
                // --- 写入根节点
                XmlNode eleRoot = xmlDoc.CreateElement(System.Convert.ToString(My.Settings.Default.ProjectName));

                xmlDoc.AppendChild(eleRoot);
                XmlElement eleDataBase = xmlDoc.CreateElement(DataBasePath.Nd1_DataBasePaths);

                eleRoot.AppendChild(eleDataBase);
                // ------------ 写入整个项目的所有工作簿的绝对路径
                foreach (Workbook wkbk in FileContents.lstWkbks)
                {
                    XmlElement eleWkbks = xmlDoc.CreateElement(DataBasePath.Nd2_WorkbooksInProject);
                    eleWkbks.InnerText = wkbk.FullName;
                    eleDataBase.AppendChild(eleWkbks);
                }

                //--------- 写入施工进度工作表
                short iProgress = (short)1;

                foreach (Worksheet tempLoopVar_sheet in FileContents.lstSheets_Progress)
                {
                    sheet = tempLoopVar_sheet;
                    XmlElement eleProgress = xmlDoc.CreateElement(DataBasePath.Nd2_Progress);
                    WriteChildNodes(xmlDoc, eleProgress, sheet);
                    eleDataBase.AppendChild(eleProgress);
                }

                //--------- 写入开挖剖面工作表
                XmlElement eleSecional = xmlDoc.CreateElement(DataBasePath.Nd2_SectionalView);

                eleDataBase.AppendChild(eleSecional);
                sheet = FileContents.Sheet_Elevation;
                WriteChildNodes(xmlDoc, eleSecional, sheet);

                //-------- 写入测点坐标工作表
                XmlElement elePoint = xmlDoc.CreateElement(DataBasePath.Nd2_PointCoordinates);

                eleDataBase.AppendChild(elePoint);
                sheet = FileContents.Sheet_PointCoordinates;
                WriteChildNodes(xmlDoc, elePoint, sheet);


                //-------- 写入测点坐标工作表
                XmlElement eleWorkingStage = xmlDoc.CreateElement(DataBasePath.Nd2_WorkingStage);

                eleDataBase.AppendChild(eleWorkingStage);
                sheet = FileContents.Sheet_WorkingStage;
                WriteChildNodes(xmlDoc, eleWorkingStage, sheet);


                //-------- 写入开挖分块平面图
                XmlElement elePlan = xmlDoc.CreateElement(DataBasePath.Nd2_PlanView);

                eleDataBase.AppendChild(elePlan);
                sheet = FileContents.Sheet_PlanView;
                WriteChildNodes(xmlDoc, elePlan, sheet);

                //保存文档
                xmlDoc.Save(this.P_FilePath);
            }