Imports UTS_Core.Undo Imports UTS_Core.UTSModule Imports UTS_Core.UTSModule.Station Public Class FrmStationPlan #Region "初始化" Public Property StationPlanCommand() As StationPlanCommandHelpers Public Property StationPlanColHelpers() As Dictionary(Of String, PlanColHelper) Property StationPlan() As StationPlan Private Property SelectRowNode() As RowNode Private Property SelectNode() As TreeNode Private Property LastSelectNode() As TreeNode Private _stationPlanUploading As Boolean ''' ''' 显示窗体 ''' ''' Public Sub ShowForm(parentControl As Control) FormBorderStyle = FormBorderStyle.None TopLevel = False Dock = DockStyle.Fill Parent = parentControl Enabled = StationPlan IsNot Nothing Show() End Sub ''' ''' 测试站修改时处理函数 ''' ''' Public Sub Station_Changed(processStation As ProcessStation) StationPlan = processStation.Packet.StationPlan Enabled = StationPlan IsNot Nothing If StationPlan IsNot Nothing Then GrpStationPlan.Controls.Clear() GrpStationPlan.Controls.Add(StationPlan.TreeView) _stationPlanUploading = True '设置更新状态,避免触发树内容变更事件 InitializeTreeView(StationPlan.TreeView) '初始化树 StationPlan.UpdateTreeViewStyle() '更新树样式 _stationPlanUploading = False End If End Sub ''' ''' 初始化站命令帮助信息 ''' Private Sub InitStationPlanCommandHelper() Try StationPlanCommand = New StationPlanCommandHelpers() StationPlanCommand.InitCommandHelper(UtsDb.LocalDbType, UtsDb.LocalConnString) Catch ex As Exception Console.WriteLine($"InitStationPlanCommandHelper Error:{ex.Message}") End Try End Sub ''' ''' 初始化站流程帮助信息 ''' Private Sub InitStationPlanColHelper() Try StationPlanColHelpers = PlanColHelper.InitPlanColHelper(UtsDb.LocalDbType, UtsDb.LocalConnString) Catch ex As Exception Console.WriteLine($"InitStationPlanColHelper Error:{ex.Message}") End Try If StationPlanColHelpers Is Nothing Then StationPlanColHelpers = New Dictionary(Of String, PlanColHelper)() End If End Sub ''' ''' 初始化行节点的风格 ''' Private Sub InitRowNodeStyles() If IO.File.Exists(UtsPath.NodeStylePath()) Then RowNode.LoadNodeStyles(UtsPath.NodeStylePath()) Else RowNode.InitNodeStyles() End If End Sub Private Sub FrmStationPlan_Load(sender As Object, e As EventArgs) Handles Me.Load InitStationPlanCommandHelper() InitStationPlanColHelper() InitRowNodeStyles() End Sub ''' ''' 根据节点找寻节点关联的行节点信息 ''' ''' ''' Private Function FindRowInfo(node As TreeNode) As RowNode Return CType(node.Tag, RowNode) End Function Private Sub InitializeTreeView(tree As TreeView) With tree .Dock = DockStyle.Fill .AllowDrop = True '允许拖拽 .ShowLines = True '显示线条 .CheckBoxes = True '显示选择框 .ShowNodeToolTips = False '不显示节点的ToolTip .HotTracking = True '移动反显 .ItemHeight = 20 '行高 .BorderStyle = BorderStyle.None .ContextMenuStrip = CmsMain RemoveHandler .ItemDrag, AddressOf TvwStationPlan_ItemDrag RemoveHandler .DragEnter, AddressOf TvwStationPlan_DragEnter RemoveHandler .DragDrop, AddressOf TvwStationPlan_DragDrop RemoveHandler .DragOver, AddressOf TvwStationPlan_DragOver RemoveHandler .AfterSelect, AddressOf TvwStationPlan_AfterSelect RemoveHandler .AfterCheck, AddressOf TvwStationPlan_AfterCheck ' RemoveHandler .KeyDown, AddressOf TvwStationPlan_KeyDown AddHandler .ItemDrag, AddressOf TvwStationPlan_ItemDrag AddHandler .DragEnter, AddressOf TvwStationPlan_DragEnter AddHandler .DragDrop, AddressOf TvwStationPlan_DragDrop AddHandler .DragOver, AddressOf TvwStationPlan_DragOver AddHandler .AfterSelect, AddressOf TvwStationPlan_AfterSelect AddHandler .AfterCheck, AddressOf TvwStationPlan_AfterCheck ' AddHandler .KeyDown, AddressOf TvwStationPlan_KeyDown End With End Sub Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown RowNodeGrid.InitializeGrid(GrdRowNode) End Sub #End Region #Region "节点拖拽" ''' ''' 开始拖拽子节点 ''' ''' ''' Private Sub TvwStationPlan_ItemDrag(sender As Object, e As ItemDragEventArgs) Dim srcNode As TreeNode = CType(e.Item, TreeNode) Dim parentRowNode As RowNode = FindRowInfo(srcNode) If parentRowNode.CanChangeLever = False Then Return DoDragDrop(e.Item, DragDropEffects.Move) End Sub ''' ''' 拖拽进入控件 ''' ''' ''' Private Sub TvwStationPlan_DragEnter(sender As Object, e As DragEventArgs) e.Effect = DragDropEffects.Move End Sub ''' ''' 拖拽松开鼠标 ''' ''' ''' Private Sub TvwStationPlan_DragDrop(sender As Object, e As DragEventArgs) '得到拖放数据,并转换为TreeNode型 Dim srcNode As TreeNode = CType(e.Data.GetData(GetType(TreeNode)), TreeNode) Dim parentRowNode As RowNode = FindRowInfo(srcNode) Dim tvwDest As TreeView = CType(sender, TreeView) Dim destNode As TreeNode = tvwDest.GetNodeAt(tvwDest.PointToClient(New Point(e.X, e.Y))) '获取拖拽所到的节点 Dim childRowNode As RowNode = FindRowInfo(destNode) If IsNothing(destNode) Then Return '未获取到节点 If destNode.Equals(srcNode) Then Return '节点未移动 Dim pNode As TreeNode = destNode.Parent While pNode IsNot Nothing If pNode.Equals(srcNode) Then Return '移动至本身的子节点 pNode = pNode.Parent End While If parentRowNode.RowLever <> childRowNode.ParentNode.RowLever Then If parentRowNode.CanChangeLever = False Then Return '不允许节点移动 End If DeleteNode(srcNode) InsertNode(childRowNode.ParentNode, parentRowNode, destNode.Index) srcNode.BackColor = Color.White '修改节点背景色 tvwDest.SelectedNode = srcNode '选中当前节点 End Sub ''' ''' 拖拽完成 ''' ''' ''' Private Sub TvwStationPlan_DragOver(sender As Object, e As DragEventArgs) End Sub #End Region #Region "数据同步与反同步" Private Sub UpdateRowNodeGridFromNode(node As TreeNode) If node Is Nothing Then Return If _cellChanged = GridCellChangedEnum.None Then _cellChanged = GridCellChangedEnum.SelectChange If _cellChanged = GridCellChangedEnum.SelectChange Then RowNodeGrid.AfterSelectUpdateGrid(GrdRowNode, FindRowInfo(node)) _cellChanged = GridCellChangedEnum.None End If End Sub ''' ''' 选中节点时,更新节点被选中的样式 ''' ''' 更新的节点对象 ''' 是否处于选中状态 Private Sub UpdateNodeStyle(node As TreeNode, selected As Boolean) Static lastColor As Color = Color.Transparent If node Is Nothing Then Return If selected Then lastColor = node.BackColor node.BackColor = Color.DodgerBlue Else node.BackColor = lastColor End If End Sub Private Sub TvwStationPlan_AfterSelect(sender As Object, e As TreeViewEventArgs) If _stationPlanUploading Then Return UpdateNodeStyle(LastSelectNode, False) '取消上一选中节点选中状态 SelectNode = StationPlan.TreeView.SelectedNode SelectRowNode = FindRowInfo(SelectNode) UpdateRowNodeGridFromNode(SelectNode) UpdateNodeStyle(SelectNode, True) '更新当前节点的选中状态 LastSelectNode = SelectNode End Sub ''' ''' 详细信息表格内容变更类型枚举值 ''' Enum GridCellChangedEnum ''' ''' 未变更 ''' None ''' ''' 加载流程时时引起的变更 ''' TestPlan ''' ''' 行节点信息修改引起的变更 ''' RowNodeInfo ''' ''' 切换选择节点引起的变更 ''' SelectChange End Enum ''' ''' 详细信息表格内容变更类型 ''' Private _cellChanged As GridCellChangedEnum = GridCellChangedEnum.None ''' ''' 行节点表,下拉框选择行 ''' Private _grdSingleRowDropRow As Integer ''' ''' 行节点表,下拉框所在列 ''' Private _grdSingleRowDropCol As Integer Private Sub GrdSingleRow_CellChange(sender As Object, e As FlexCell.Grid.CellChangeEventArgs) Handles GrdRowNode.CellChange If SelectNode Is Nothing Then Return If _cellChanged = GridCellChangedEnum.None Then _cellChanged = GridCellChangedEnum.RowNodeInfo If _cellChanged = GridCellChangedEnum.RowNodeInfo Then If e.Col = RowNodeGrid.ColNameEnum.ColValue Then Manager.RunCommand(New RowNodeCommand(SelectRowNode, e.Row, GrdRowNode.Cell(e.Row, e.Col).Text)) End If _cellChanged = GridCellChangedEnum.None End If End Sub ''' ''' 单行信息表格命令修改后,同步刷新本身信息 ''' Private Sub GrdSingleRowInfoCommandChanged(commandType As String, commandName As String) Dim planCommand As StationPlanCommand = StationPlanCommand.GetCommand(commandType, commandName) If planCommand IsNot Nothing Then '拷贝所有参数到当前节点信息中 SelectRowNode.Parameters.Clear() For Each cmdParam As CommandParam In planCommand.Params SelectRowNode.Parameters.Add(cmdParam.Clone()) Next '更新行节点信息表格内容 GrdRowNode.Rows = RowNodeGrid.RowNameEnum.Parameters + planCommand.Params.Count For idx As Integer = 0 To planCommand.Params.Count - 1 Dim row As Integer = RowNodeGrid.RowNameEnum.Parameters + idx GrdRowNode.Cell(row, RowNodeGrid.ColNameEnum.ColName).Text = planCommand.Params(idx).Desc GrdRowNode.Cell(row, RowNodeGrid.ColNameEnum.ColValue).Text = planCommand.Params(idx).Value Next Else GrdRowNode.Rows = RowNodeGrid.RowNameEnum.Parameters + 1 GrdRowNode.Cell(RowNodeGrid.RowNameEnum.Parameters, RowNodeGrid.ColNameEnum.ColName).Text = RowNodeGrid.RowNameEnum.Parameters.ToString() GrdRowNode.Cell(RowNodeGrid.RowNameEnum.Parameters, RowNodeGrid.ColNameEnum.ColValue).Text = "" End If End Sub ''' ''' 下拉框选择对象事件 ''' ''' ''' Private Sub GrdSingleRow_ComboClick(sender As Object, e As FlexCell.Grid.ComboClickEventArgs) Handles GrdRowNode.ComboClick If SelectNode Is Nothing Then Return Select Case _grdSingleRowDropRow Case RowNodeGrid.RowNameEnum.CommandType '如果类型变化则,清空命令 Dim cmdType As String = GrdRowNode.Cell(RowNodeGrid.RowNameEnum.CommandType, RowNodeGrid.ColNameEnum.ColValue).Text If String.Compare(SelectRowNode.CommandType, cmdType) <> 0 Then GrdRowNode.Cell(RowNodeGrid.RowNameEnum.Command, RowNodeGrid.ColNameEnum.ColValue).Text = "" GrdSingleRowInfoCommandChanged(cmdType, "") End If Case RowNodeGrid.RowNameEnum.Command Dim cmdName As String = GrdRowNode.Cell(RowNodeGrid.RowNameEnum.Command, RowNodeGrid.ColNameEnum.ColValue).Text If String.Compare(SelectRowNode.Command, cmdName) <> 0 Then GrdSingleRowInfoCommandChanged(SelectRowNode.CommandType, cmdName) End If Case RowNodeGrid.RowNameEnum.RowType End Select End Sub ''' ''' 表格下拉框出现时触发事件 ''' ''' ''' Private Sub GrdSingleRow_ComboDropDown(sender As Object, e As FlexCell.Grid.ComboDropDownEventArgs) Handles GrdRowNode.ComboDropDown _grdSingleRowDropRow = e.Row _grdSingleRowDropCol = e.Col Select Case e.Row Case RowNodeGrid.RowNameEnum.CommandType GrdRowNode.ComboBox(0).Items.Clear() GrdRowNode.ComboBox(0).Items.AddRange(StationPlanCommand.GetCommandTypes()) Case RowNodeGrid.RowNameEnum.Command GrdRowNode.ComboBox(0).Items.Clear() GrdRowNode.ComboBox(0).Items.AddRange(StationPlanCommand.GetCommandNames(SelectRowNode.CommandType)) Case RowNodeGrid.RowNameEnum.RowType GrdRowNode.ComboBox(0).Items.Clear() GrdRowNode.ComboBox(0).Items.Add(RowNode.RowTypeEnum.Control) GrdRowNode.ComboBox(0).Items.Add(RowNode.RowTypeEnum.Flow) GrdRowNode.ComboBox(0).Items.Add(RowNode.RowTypeEnum.Module) End Select End Sub #End Region #Region "RowNode 选择行提示" 'Private _lastSingleRowSelCol As Integer Private _lastSingleRowSelRow As Integer ''' ''' 更新流程列名提示 ''' ''' Private Sub UpdatePlanColNameTip(colName As String) If StationPlanColHelpers.ContainsKey(colName) Then Dim colHelper As PlanColHelper = StationPlanColHelpers.Item(colName) RtxColTip.SuspendLayout() RtxColTip.Clear() RtxColTip.AppendText($"{colHelper.ColName}{vbCrLf}") RtxColTip.AppendText($"类型:{colHelper.ColType}{vbCrLf}") RtxColTip.AppendText($"描述:{colHelper.ColDesc}{vbCrLf}") RtxColTip.ResumeLayout(False) End If End Sub ''' ''' 更新流程命令提示 ''' ''' ''' ''' ''' Private Sub UpdateCommandTip(colName As String, commandType As String, commandName As String, paramIndex As Integer) Dim planCommand As StationPlanCommand = StationPlanCommand.GetCommand(commandType, commandName) If planCommand IsNot Nothing Then RtxColTip.SuspendLayout() RtxColTip.Clear() RtxColTip.AppendText($"{colName}{vbCrLf}") RtxColTip.AppendText($"类型:{planCommand.Params(paramIndex).Type}{vbCrLf}") RtxColTip.AppendText($"上限:{planCommand.Params(paramIndex).UpperLimit}{vbCrLf}") RtxColTip.AppendText($"下限:{planCommand.Params(paramIndex).LowerLimit}{vbCrLf}") RtxColTip.AppendText($"描述:{planCommand.Params(paramIndex).Desc}{vbCrLf}") RtxColTip.ResumeLayout(False) Else RtxColTip.AppendText($"{colName}{vbCrLf}") End If End Sub ''' ''' 单行信息表格更新当前行 ''' ''' Private Sub UpdateSingleRowTip(row As Integer) Dim colName As String = GrdRowNode.Cell(row, RowNodeGrid.ColNameEnum.ColName).Text If row >= RowNodeGrid.RowNameEnum.Parameters Then Dim commandType As String = GrdRowNode.Cell(RowNodeGrid.RowNameEnum.CommandType, RowNodeGrid.ColNameEnum.ColValue).Text Dim command As String = GrdRowNode.Cell(RowNodeGrid.RowNameEnum.Command, RowNodeGrid.ColNameEnum.ColValue).Text If String.IsNullOrEmpty(command) Then UpdatePlanColNameTip(colName) Else UpdateCommandTip(colName, commandType, command, row - RowNodeGrid.RowNameEnum.Parameters) End If Else UpdatePlanColNameTip(colName) End If End Sub Private Sub SingleRowSelChange(row As Integer) If _lastSingleRowSelRow = row Then Return If _lastSingleRowSelRow >= GrdRowNode.Rows Then Return '新增命令切换处理 GrdRowNode.Cell(_lastSingleRowSelRow, RowNodeGrid.ColNameEnum.ColName).FontBold = False GrdRowNode.Cell(row, RowNodeGrid.ColNameEnum.ColName).FontBold = True UpdateSingleRowTip(row) '更新列提示 _lastSingleRowSelRow = row End Sub Private Sub GrdRowNode_SelChange(sender As Object, e As FlexCell.Grid.SelChangeEventArgs) Handles GrdRowNode.SelChange SingleRowSelChange(e.FirstRow) End Sub #End Region #Region "增删节点" ''' ''' 删除节点 ''' ''' Private Function DeleteNode(node As TreeNode) As Boolean If node Is Nothing Then Return False Dim rowNode As RowNode = FindRowInfo(node) If rowNode.CanDelete = False Then Return False Manager.RunCommand(New RowNodeCommand2(rowNode.ParentNode, rowNode, RowNodeCommand2.ChangeType.Remove)) Return True End Function Private Sub ClearAllNode() StationPlan.CreateNewStationPlan() End Sub ''' ''' 上移节点 ''' ''' Private Sub MoveUpNode(node As TreeNode) Dim index As Integer = node.Index If index = 0 Then Return Dim rowNode As RowNode = FindRowInfo(node) Manager.RunCommand(New RowNodeCommand2(rowNode.ParentNode, rowNode, RowNodeCommand2.ChangeType.MoveUp)) rowNode.TreeView.SelectedNode = rowNode.TreeNode End Sub ''' ''' 下移节点 ''' ''' Private Sub MoveDownNode(node As TreeNode) Dim index As Integer = node.Index If index = node.Parent.Nodes.Count - 1 Then Return Dim rowNode As RowNode = FindRowInfo(node) Manager.RunCommand(New RowNodeCommand2(rowNode.ParentNode, rowNode, RowNodeCommand2.ChangeType.MoveDown)) rowNode.TreeView.SelectedNode = rowNode.TreeNode End Sub ''' ''' 左移节点 ''' ''' Private Sub MoveLeftNode(node As TreeNode) If node.Level = 0 Then Return Dim rowNode As RowNode = FindRowInfo(node) If rowNode.CanChangeLever = False Then Return Manager.RunCommand(New RowNodeCommand2(rowNode.ParentNode, rowNode, RowNodeCommand2.ChangeType.MoveLeft)) rowNode.TreeView.SelectedNode = rowNode.TreeNode End Sub ''' ''' 右移节点 ''' ''' Private Sub MoveRightNode(node As TreeNode) If node.Index = 0 Then Return Dim rowNode As RowNode = FindRowInfo(node) If rowNode.CanChangeLever = False Then Return Manager.RunCommand(New RowNodeCommand2(rowNode.ParentNode, rowNode, RowNodeCommand2.ChangeType.MoveRight)) rowNode.TreeView.SelectedNode = rowNode.TreeNode End Sub ''' ''' 选中节点 ''' ''' Private Sub CheckNode(node As TreeNode) If node.Checked Then node.Checked = False Else node.Checked = True End If End Sub ''' ''' 全选节点 ''' ''' ''' Private Sub CheckAll(tvw As TreeView, checked As Boolean) For Each node As TreeNode In tvw.Nodes node.Checked = checked Next End Sub ''' ''' 根据节点当前状态,展开或折叠节点 ''' ''' Private Sub ExpendNode(node As TreeNode) If node.IsExpanded Then node.Collapse() Else node.Expand() End If End Sub ''' ''' 在指定父节点下,增加子节点 ''' ''' 添加子节点的树节点 Private Sub AddNode(node As TreeNode) If node Is Nothing Then Return Dim parentRowNode As RowNode = FindRowInfo(node) Dim rowNode As New RowNode With {.RowType = RowNode.RowTypeEnum.Flow} If parentRowNode.CanAddChildNode Then Manager.RunCommand(New RowNodeCommand2(parentRowNode, rowNode, RowNodeCommand2.ChangeType.Add)) Else Manager.RunCommand(New RowNodeCommand2(parentRowNode.ParentNode, rowNode, RowNodeCommand2.ChangeType.Insert, parentRowNode.RowIndex + 1)) End If End Sub ''' ''' 在指定的行节点下,添加指定行节点 ''' ''' ''' Private Sub AddNode(parentRowNode As RowNode, rowNode As RowNode) If parentRowNode.CanAddChildNode Then Manager.RunCommand(New RowNodeCommand2(parentRowNode, rowNode, RowNodeCommand2.ChangeType.Add)) Else Manager.RunCommand(New RowNodeCommand2(parentRowNode.ParentNode, rowNode, RowNodeCommand2.ChangeType.Insert, parentRowNode.RowIndex + 1)) End If End Sub Private Sub InsertNode(parentRowNode As RowNode, rowNode As RowNode, index As Integer) If parentRowNode.CanAddChildNode Then Manager.RunCommand(New RowNodeCommand2(parentRowNode, rowNode, RowNodeCommand2.ChangeType.Insert, index)) Else Manager.RunCommand(New RowNodeCommand2(parentRowNode.ParentNode, rowNode, RowNodeCommand2.ChangeType.Add)) End If End Sub ''' ''' 读取XML,加载树状视图 ''' Private Sub LoadTreeViewFormXml() _stationPlanUploading = True Dim revStationPlanPath As String = $"{UtsPath.StationPacketTestPlanDirPath(StationPlan.ParentPacket.Name)}\Main.xml" Try StationPlan.LoadFromXml(revStationPlanPath) Manager.ClearCommands() Catch ex As Exception MsgBox($"加载测试站流程发生错误,{ex.Message}") StationPlan.CreateNewStationPlan() End Try _stationPlanUploading = False End Sub ''' ''' 读取XML,加载树状视图 ''' Private Sub LoadTreeViewFormXml(revStationPlanPath As String) _stationPlanUploading = True Try StationPlan.LoadFromXml(revStationPlanPath) Manager.ClearCommands() Catch ex As Exception MsgBox($"加载测试站流程发生错误,{ex.Message}") StationPlan.CreateNewStationPlan() End Try _stationPlanUploading = False End Sub ''' ''' 将树状视图导出为Xml ''' Private Sub ExportTreeViewToXml() Dim revStationPlanPath As String = $"{UtsPath.StationPacketTestPlanDirPath(StationPlan.ParentPacket.Name)}\Main.xml" StationPlan.ExportToXml(revStationPlanPath) End Sub Private Sub TsBtnAddNode_Click(sender As Object, e As EventArgs) Handles TsBtnAddNode.Click AddNode(SelectNode) End Sub Private Sub TsBtnDeleteNode_Click(sender As Object, e As EventArgs) Handles TsBtnDeleteNode.Click DeleteNode(SelectNode) End Sub Private Sub TsBtnClearAll_Click(sender As Object, e As EventArgs) Handles TsBtnClearAll.Click If MsgBox("该操作无法撤销,是否继续清空节点?", MsgBoxStyle.OkCancel) = MsgBoxResult.Ok Then If _stationPlanUploading Then Return _stationPlanUploading = True ClearAllNode() '清空树节点 Manager.ClearCommands() '清空撤销缓存 _stationPlanUploading = False If StationPlan.TreeView.Nodes.Count > 0 Then StationPlan.TreeView.SelectedNode = StationPlan.TreeView.Nodes(0) End If End Sub Private Sub TsBtnMoveUp_Click(sender As Object, e As EventArgs) Handles TsBtnMoveUp.Click MoveUpNode(SelectNode) End Sub Private Sub TsBtnMoveDown_Click(sender As Object, e As EventArgs) Handles TsBtnMoveDown.Click MoveDownNode(SelectNode) End Sub Private Sub TsBtnMoveLeft_Click(sender As Object, e As EventArgs) Handles TsBtnMoveLeft.Click MoveLeftNode(SelectNode) End Sub Private Sub TsBtnMoveRight_Click(sender As Object, e As EventArgs) Handles TsBtnMoveRight.Click MoveRightNode(SelectNode) End Sub Private Sub TsBtnNodeCheck_Click(sender As Object, e As EventArgs) Handles TsBtnNodeCheck.Click CheckNode(SelectNode) End Sub Private Sub TsBtnAllCheck_Click(sender As Object, e As EventArgs) Handles TsBtnAllCheck.Click CheckAll(StationPlan.TreeView, True) End Sub Private Sub TsBtnAllUncheck_Click(sender As Object, e As EventArgs) Handles TsBtnAllUncheck.Click CheckAll(StationPlan.TreeView, False) End Sub Private Sub TsBtnCollapseAll_Click(sender As Object, e As EventArgs) Handles TsBtnCollapseAll.Click StationPlan.TreeView.CollapseAll() End Sub Private Sub TsBtnAllExpend_Click(sender As Object, e As EventArgs) Handles TsBtnExpandAll.Click StationPlan.TreeView.ExpandAll() End Sub Private Sub TsBtnNodeExpend_Click(sender As Object, e As EventArgs) Handles TsBtnNodeExpend.Click ExpendNode(SelectNode) End Sub Private Sub TsBtnOpen_Click(sender As Object, e As EventArgs) Handles TsBtnOpen.Click Using xml As New OpenFileDialog xml.Filter = $"流程文件(*.xml)|*.xml" If xml.ShowDialog() = DialogResult.OK Then LoadTreeViewFormXml(xml.FileName) End If End Using End Sub Private Sub TsBtnLoad_Click(sender As Object, e As EventArgs) Handles TsBtnLoad.Click LoadTreeViewFormXml() End Sub Private Sub TsBtnSave_Click(sender As Object, e As EventArgs) Handles TsBtnSave.Click ExportTreeViewToXml() End Sub ''' ''' 当前节点勾选状态变更时,同步修改其子节点的勾选状态 ''' ''' ''' Private Sub AfterCheckUpdateChildRowNode(rowNode As RowNode, node As TreeNode) For i As Integer = 0 To node.Nodes.Count - 1 Dim cRowNode As RowNode = CType(rowNode.RowNodes.Item(i), RowNode) cRowNode.Action = rowNode.Action cRowNode.UpdateTreeNodeText(node.Nodes.Item(i)) '更新节点文本 node.Nodes.Item(i).Checked = node.Checked AfterCheckUpdateChildRowNode(cRowNode, node.Nodes.Item(i)) Next End Sub ''' ''' 当前节点勾选状态变更时,检查同级节点状态是否相同,更新父节点勾选状态 ''' ''' ''' Private Sub AfterCheckUpdateParentRowNode(rowNode As RowNode, node As TreeNode) If rowNode.RowLever = 0 Then Return If rowNode.ParentNode.Action = rowNode.Action Then Return For i As Integer = 0 To rowNode.ParentNode.RowNodes.Count - 1 Dim cRowNode As RowNode = CType(rowNode.ParentNode.RowNodes(i), RowNode) If cRowNode.Action <> rowNode.Action Then Return Next rowNode.ParentNode.Action = rowNode.Action rowNode.ParentNode.UpdateTreeNodeText(node.Parent) node.Parent.Checked = node.Checked AfterCheckUpdateParentRowNode(rowNode.ParentNode, node.Parent) End Sub Private Sub TvwStationPlan_AfterCheck(sender As Object, e As TreeViewEventArgs) If _stationPlanUploading Then Return '设计修改父节点与子节点勾选信息,防止重复处理事件 _stationPlanUploading = True Dim rowNode As RowNode = FindRowInfo(e.Node) rowNode.Action = e.Node.Checked rowNode.UpdateTreeNodeText(e.Node) '更新节点文本 If e.Node.Equals(SelectNode) Then UpdateRowNodeGridFromNode(e.Node) '更新表格显示 End If AfterCheckUpdateChildRowNode(rowNode, e.Node) AfterCheckUpdateParentRowNode(rowNode, e.Node) _stationPlanUploading = False End Sub Private Sub TsBtnStyle_Click(sender As Object, e As EventArgs) Handles TsBtnStyle.Click Using dlgStyle As New DlgStationPlanStyle If dlgStyle.ShowDialog() = DialogResult.OK Then StationPlan.UpdateTreeViewStyle() '保存样式 RowNode.SaveNodeStyles(UtsPath.NodeStylePath) End If End Using End Sub #End Region #Region "保存与读取节点文件" Private Sub SaveNodeFile(node As TreeNode) If node Is Nothing Then Return Using dialog As New SaveFileDialog dialog.Title = $"请输入需要保存节点的文件名" dialog.AddExtension = True dialog.Filter = $"节点文件(*.xml)|*.xml" If dialog.ShowDialog() <> DialogResult.OK Then Return Dim rowNode As RowNode = FindRowInfo(node) rowNode.ExportToXml(dialog.FileName) End Using End Sub Private Sub LoadNodeFile(node As TreeNode) If node Is Nothing Then Return Using dialog As New OpenFileDialog dialog.Title = $"请选择需要加载的节点文件" dialog.Filter = $"节点文件(*.xml)|*.xml" dialog.Multiselect = False If dialog.ShowDialog() <> DialogResult.OK Then Return _stationPlanUploading = True Dim parentRowNode As RowNode = FindRowInfo(node) Dim childRowNode As New RowNode childRowNode.LoadFormXml(dialog.FileName) AddNode(parentRowNode, childRowNode) If node.IsExpanded = False Then node.Expand() '展开当前节点 _stationPlanUploading = False End Using End Sub Private Sub MsiSaveNodeFile_Click(sender As Object, e As EventArgs) Handles MsiSaveNodeFile.Click SaveNodeFile(SelectNode) End Sub Private Sub MsiLoadNodeFile_Click(sender As Object, e As EventArgs) Handles MsiLoadNodeFile.Click LoadNodeFile(SelectNode) End Sub #End Region #Region "撤销重做" ''' ''' 撤销重做操作类 ''' ''' Private Property Manager() As New CommandManager ''' ''' 撤销节点操作 ''' Private Sub UndoNode() Manager.Undo() UpdateRowNodeGridFromNode(SelectNode) '更新表格显示 End Sub ''' ''' 重做节点操作 ''' Private Sub RedoNode() Manager.Redo() UpdateRowNodeGridFromNode(SelectNode) '更新表格显示 End Sub #End Region #Region "节点复制剪切粘贴操作" Private Property CloneRowNode As RowNode ''' ''' 复制节点 ''' Private Sub CopyNode(node As TreeNode) If node Is Nothing Then Return CloneRowNode = FindRowInfo(node).Clone() End Sub ''' ''' 剪切节点 ''' Private Sub CutNode(node As TreeNode) If node Is Nothing Then Return If DeleteNode(node) Then CloneRowNode = FindRowInfo(node) End If End Sub ''' ''' 粘贴节点 ''' Private Sub PasteNode(node As TreeNode) If CloneRowNode Is Nothing Then Return If node Is Nothing Then Return Dim parentRowNode As RowNode = FindRowInfo(node) Dim childRowNode As RowNode = CloneRowNode.Clone() AddNode(parentRowNode, childRowNode) If node.IsExpanded = False Then node.Expand() End Sub Private Sub MsiCopyNode_Click(sender As Object, e As EventArgs) Handles MsiCopyNode.Click CopyNode(SelectNode) End Sub Private Sub MsiCutNode_Click(sender As Object, e As EventArgs) Handles MsiCutNode.Click CutNode(SelectNode) End Sub Private Sub MsiNodePaste_Click(sender As Object, e As EventArgs) Handles MsiNodePaste.Click PasteNode(SelectNode) End Sub Private Sub MsiUndo_Click(sender As Object, e As EventArgs) Handles MsiUndo.Click UndoNode() End Sub Private Sub MsiRedo_Click(sender As Object, e As EventArgs) Handles MsiRedo.Click RedoNode() End Sub ''' ''' 快捷键操作 ''' ''' ''' Private Sub TvwStationPlan_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown If e.Modifiers = Keys.Control Then Select Case e.KeyCode Case Keys.C '复制 If StationPlan.TreeView.Focused = False Then Return CopyNode(SelectNode) Case Keys.X '剪切 If StationPlan.TreeView.Focused = False Then Return CutNode(SelectNode) Case Keys.V '粘贴 If StationPlan.TreeView.Focused = False Then Return PasteNode(SelectNode) Case Keys.Z '撤销 UndoNode() Case Keys.Y '重做 RedoNode() Case Keys.O '加载 LoadTreeViewFormXml() Case Keys.S '保存 ExportTreeViewToXml() Case Keys.Up '节点上移 MoveUpNode(SelectNode) Case Keys.Down '节点下移 MoveDownNode(SelectNode) Case Keys.Left '节点左移 MoveLeftNode(SelectNode) Case Keys.Right '节点移动 MoveRightNode(SelectNode) Case Keys.D '增加节点 AddNode(SelectNode) Case Keys.R '删除节点 DeleteNode(SelectNode) End Select ElseIf e.Modifiers = Keys.Alt Then Select Case e.KeyCode Case Keys.O '加载指定节点文件 LoadNodeFile(SelectNode) Case Keys.S '保存指定节点 SaveNodeFile(SelectNode) End Select ElseIf e.Modifiers = Keys.None Then Select Case e.KeyCode Case Keys.Back '删除 If StationPlan.TreeView.Focused = False Then Return DeleteNode(SelectNode) End Select End If End Sub Private Sub GrdRowNode_Load(sender As Object, e As EventArgs) Handles GrdRowNode.Load End Sub #End Region End Class