Imports System.Drawing Imports System.Reflection.Emit Imports System.Text Imports System.Windows.Forms Imports FlexCell Imports UTS_Core.UTSModule.Production Imports UTS_Core.UTSModule.Test.Command Imports UTS_Core.UTSModule.Test.StatusMonitor Namespace UTSModule.Station Public Class StationPlanGrid 'ActionEn属性:注意这个属性不仅仅由Action列决定,还由他的父节点的Action属性决定 'ActionEn属性是隐性的,表格中看不到,表格中只能看到本行的Action值 '每一行的ActionEn属性由它本身的Action和往祖辈方向溯源的所有级的ActionEn值决定 '只有Level=1的Module节点,ActionEn属性等于其Action值,因为在往上溯源就是FixModule,而FixModule是肯定为True的 'ActionEn属性为False时,该行为灰色 Public Structure RowNodeInfo '用于保存每一行的关键信息 Dim RowIdx As Integer '表格行号’ Dim NodeType As Integer Dim NodeLevel As Integer Dim NodeIdx As Integer '同级节点顺序’ Dim ActionVal As Boolean 'Action框勾选值 Dim ActionEn As Boolean 'ActionEn,由自身的Action值和父节点的Action值共同决定 Dim CmdType As String '命令类型’ Dim TextColor As Color '文本颜色 Dim FatherNodeIdxLst As List(Of Integer) '保存父级节点的行号 Dim IsRecord As Boolean '是否保存 Dim Description As String Dim RecordName As String End Structure Private _grd As Grid Private _cms As ContextMenuStrip Private _drawCol As Integer Private _drawStartRow As Integer Private _debugMode As Boolean Private _headNode As RowNode Private ReadOnly _showNodeIcon As Boolean ''' 处于更新表格状态中,不触发表格单元格修改事件 Private _uploading As Boolean ''' 多个参数间的分割符号 Private ReadOnly _paramChar As Char ''' 当前活动节点 Public ActiveNode As RowNode ''' 节点选择改变事件 Public Event PlanNodeSelectChanged(ByVal sender As Object, ByVal e As PlanNodeSelectChangedEventArgs) ''' 节点文本被修改事件 Public Event RowNodeTextChanged(ByVal sender As Object, ByVal e As RowNodeChangedEventArgs) ''' 测试命令管理器 Private ReadOnly _testCmdManager As TestCmdManager ''' 错误代码管理器 Private ReadOnly _errCodeManager As ErrCodeManager Private gMouseOldRow As Integer '记录鼠标移动前的行号 Private gMouseOldCol As Integer Private gOldRowType As Integer Private gRowType As Integer Private gDescTextColor As Brush 'description cell 文字颜色 Public gRowNodeInfo() As RowNodeInfo '用于保存每一行的关键信息,如有修改,使用前调用UpdateGridActionInfo刷新一次 Private gIsGri_UpdateGridActionInfo_EventReady As Boolean = True 'UpdateGridActionInfo 函数加锁,防止嵌套执行 Private gIsGri_MouseMove_EventReady As Boolean = True 'MoveMove 函数加锁,防止嵌套执行 Sub New() NodeStartRow = 1 _drawCol = ColNames.Description _showNodeIcon = False _uploading = False _paramChar = "#"c _testCmdManager = TestCmdManager.CreateManager() _errCodeManager = ErrCodeManager.CreateManager() End Sub ''' ''' 屏蔽表格引发自定义事件,避免行节点内容修改,todo:暂未完成 ''' ''' Public Property SkipEvent() As Boolean Property DebugMode() As Boolean Get Return _debugMode End Get Set(value As Boolean) _debugMode = value UpdateColVisible() End Set End Property Property Grid() As Grid Get Return _grd End Get Set(value As Grid) _grd = value InitializeGrid() ' RemoveHandler _grd.OwnerDrawCell, AddressOf Grid_OwnerDrawCell RemoveHandler _grd.Click, AddressOf Grid_Click RemoveHandler _grd.CellChange, AddressOf Grid_CellChange RemoveHandler _grd.SelChange, AddressOf Grid_SelChange RemoveHandler _grd.ComboDropDown, AddressOf Grid_ComboDropDown RemoveHandler _grd.ComboClick, AddressOf Grid_ComboClick RemoveHandler _grd.MouseMove, AddressOf Grid_MouseMove RemoveHandler _grd.EnterRow, AddressOf Grid_EnterRow RemoveHandler _grd.MouseLeave, AddressOf Grid_MouseLeave RemoveHandler _grd.MouseEnter, AddressOf Grid_MouseEnter ' AddHandler _grd.OwnerDrawCell, AddressOf Grid_OwnerDrawCell AddHandler _grd.Click, AddressOf Grid_Click AddHandler _grd.CellChange, AddressOf Grid_CellChange AddHandler _grd.SelChange, AddressOf Grid_SelChange AddHandler _grd.ComboDropDown, AddressOf Grid_ComboDropDown AddHandler _grd.ComboClick, AddressOf Grid_ComboClick AddHandler _grd.MouseMove, AddressOf Grid_MouseMove AddHandler _grd.EnterRow, AddressOf Grid_EnterRow AddHandler _grd.MouseLeave, AddressOf Grid_MouseLeave AddHandler _grd.MouseEnter, AddressOf Grid_MouseEnter _grd.ComboBox(ColNames.CommandType).Items.Clear() _grd.ComboBox(ColNames.CommandType).Items.AddRange(_testCmdManager.GetCommandTypes()) _grd.ComboBox(ColNames.ErrorCode).Items.Clear() _grd.ComboBox(ColNames.ErrorCode).Items.AddRange(_errCodeManager.GetAllCodeAndMsg()) End Set End Property ''' ''' 对第二行的Action执行一遍操作,以触发更新事件 ''' Public Sub GridUpdateEventTrigger(grd As Grid) Dim tmpCheckValue As Boolean = grd.Cell(2, ColNames.Action).BooleanValue grd.Cell(2, ColNames.Action).Text = (Not tmpCheckValue).ToString grd.Cell(2, ColNames.Action).Text = (tmpCheckValue).ToString End Sub Private _autoRedraw As Integer = 0 Private Sub LockGridAutoRedraw() If _autoRedraw = 0 Then _grd.AutoRedraw = False _autoRedraw += 1 End Sub Private Sub UnLockGridAutoRedraw() _autoRedraw -= 1 If _autoRedraw = 0 Then _grd.AutoRedraw = True _grd.Refresh() End If End Sub Private gCopyWholeRows As Integer '整行复制时记录行数 Private gCopyRow As Integer '整行复制时记录行数 Private gIsCopyRowDataReady As Boolean = False '整行复制时标记,只能复制一次 Public Sub MultiLineCopyData() Dim tmpFrisRow As Integer = _grd.Selection.FirstRow Dim tmpLastRow As Integer = _grd.Selection.LastRow gCopyWholeRows = tmpLastRow - tmpFrisRow + 1 _grd.Range(tmpFrisRow, ColNames.Action, tmpLastRow, _grd.Cols - 1).CopyData() End Sub Public Sub MultiLinePasteData() Dim tmpFrisRow As Integer = _grd.Selection.FirstRow LockGridAutoRedraw() '插入节点 NodeAdd(gCopyWholeRows) _grd.Range(tmpFrisRow, ColNames.Action, tmpFrisRow + gCopyWholeRows, _grd.Cols - 1).PasteData() UnLockGridAutoRedraw() End Sub '离开表格时活动单元格背景颜色 Private leaveColor As Color = Color.White '离开表格时活动单元格行号 Private leaveRow As Integer = 0 ''' ''' 光标离开grd表格时,黄色底色切换到选中行 ''' Public Sub Grid_MouseLeave(sender As Object, e As EventArgs) If _grd.EditorVisible Then Return '处于编辑状态 If _grd.ActiveCell.Row <= 0 Then Return leaveRow = _grd.ActiveCell.Row leaveColor = _grd.ActiveCell.BackColor _grd.Range(leaveRow, ColNames.Result, leaveRow, ColNames.ErrorMessage).BackColor = Color.LightCyan End Sub ''' ''' 光标进入grd表格时,原底色切换到选中行 ''' Public Sub Grid_MouseEnter(sender As Object, e As EventArgs) If _grd.EditorVisible Then Return '处于编辑状态 If leaveRow <= 0 Then Return Try _grd.Range(leaveRow, ColNames.Result, leaveRow, ColNames.ErrorMessage).BackColor = leaveColor Catch ex As Exception End Try End Sub ''' ''' 根据CmdType 和 isAction 返回该行字体颜色 ''' ''' Public Function setRowTextForeColor(rowCmdType As String, isAction As Boolean, Optional rowNodeType As RowNode.RowTypeEnum = RowNode.RowTypeEnum.Flow) As Color If isAction = True Then If rowNodeType = RowNode.RowTypeEnum.Flow Then Select Case rowCmdType Case "System" Return Color.DarkSlateGray Case "ComPort" Return Color.DarkCyan Case "UtsComPort" Return Color.SeaGreen Case "Converter" Return Color.DarkOrange Case "Process" Return Color.DarkBlue Case Else Return Color.Black End Select ElseIf rowNodeType = RowNode.RowTypeEnum.Module Then Return Color.DeepPink ElseIf rowNodeType = RowNode.RowTypeEnum.FixedModule Then Return Color.Blue End If Else Return Color.LightGray End If End Function ''' ''' 鼠标移动到节点位置时所有子节点背景着色 ''' Private Sub Mouse_MoveOnNode_BackColorRepain(grd As Grid, rowType As Integer, startRowIdx As Integer, backColor As Color) '起始行NodeLevel Dim startRowNodeLevel As Integer = GetRowNodeLevel(grd, startRowIdx) '结束行号 Dim endRowNodeIdx As Integer '当前行行号和node level Dim tmpCurrRowIdx As Integer = startRowIdx Dim tmpCurrRowNodeLevel As Integer = GetRowNodeLevel(grd, tmpCurrRowIdx) '判断当前行Row type = 1,记录下本行的NodeLevel = tempNodeLevel,记录NodeLstIndx If rowType = RowNode.RowTypeEnum.Module Then '从起始行开始往下遍历 Do If tmpCurrRowIdx < Grid.Rows Then '遍历到最大行还未结束 tmpCurrRowIdx = tmpCurrRowIdx + 1 tmpCurrRowNodeLevel = GetRowNodeLevel(grd, tmpCurrRowIdx) Else Return End If Loop Until tmpCurrRowNodeLevel <= startRowNodeLevel Or tmpCurrRowIdx >= Grid.Rows '再次遍历到与起始行同级或更高级别的行,就算是该节点遍历结束 endRowNodeIdx = tmpCurrRowIdx - 1 '底色着色 LockGridAutoRedraw() grd.Range(startRowIdx, ColNames.Result, endRowNodeIdx, ColNames.ErrorMessage).BackColor = backColor UnLockGridAutoRedraw() End If End Sub #Region "修改待删除" ''' ''' FixModule节点Action变化时子节点字体重新着色 ''' ''' Public Function getRowActionEn(grd As Grid, row As Integer) As Boolean UpdateGridActionInfo(grd) Return gRowNodeInfo(row).ActionEn End Function ''' ''' FixModule节点Action变化时子节点字体重新着色 ''' Private Sub NodeAction_Change(grd As Grid, rowType As Integer, startRowIdx As Integer, isAction As Boolean) '刷新表格数据 UpdateGridActionInfo(grd) '节点关系发生变化后,重新刷新数组变量 '重新着色 ' UpdateGridInfo(grd) '重新将表格内容更新到数组变量中,如果没有节点变化,调用这个更新即可 Grid_Repain_By_ActionEn(grd) '根据刷新的数据,重新着色 End Sub ''' ''' 根据总表状态对单元格字体重新着色 ''' Private Sub Grid_Repain_By_ActionEn(grd As Grid) ''逐行着色 Dim idx As Integer Dim tmpRowColor As Color grd.AutoRedraw = False '关闭更新,加快界面刷新速度 For idx = 1 To grd.Rows - 1 'todo:修改过程注释错误 ' tmpRowColor = setRowTextForeColor(gRowNodeInfo(idx).CmdType, gRowNodeInfo(idx).ActionEn, gRowNodeInfo(idx).NodeType) '获取选颜色 grd.Range(idx, ColNames.Result, idx, ColNames.ErrorMessage).ForeColor = tmpRowColor '着色 If gRowNodeInfo(idx).IsRecord = False Then grd.Cell(idx, ColNames.RecordName).ForeColor = Color.LightGray '着色 End If If gRowNodeInfo(idx).CmdType = "" And gRowNodeInfo(idx).Description = "" Then '空白行字体与底色同色,避免对编辑产生干扰 grd.Range(idx, ColNames.Result, idx, ColNames.ErrorMessage).ForeColor = grd.Cell(idx, ColNames.Description).BackColor '着色 End If If gRowNodeInfo(idx).NodeType = RowNode.RowTypeEnum.FixedModule Then grd.Range(idx, ColNames.CommandType, idx, ColNames.ErrorMessage).ForeColor = grd.Cell(idx, ColNames.Description).BackColor '着色 End If Next grd.Refresh() '刷新表格 grd.AutoRedraw = True End Sub #End Region ''' ''' 遍历表格,并更新到全局数组 ''' ''' Private Sub UpdateGridInfo(grd As Grid) 'If grd.EditorVisible Then Return '处于编辑状态 Dim idx As Integer ReDim gRowNodeInfo(grd.Rows) '先将参数遍历后写入整体数组 For idx = 0 To grd.Rows - 1 gRowNodeInfo(idx).ActionVal = grd.Cell(idx, ColNames.Action).BooleanValue '当前行 Action gRowNodeInfo(idx).NodeLevel = GetRowNodeLevel(grd, idx) '当前行的 NodeLevel gRowNodeInfo(idx).NodeType = GetRowType(grd, idx) '当前行的 NodeType gRowNodeInfo(idx).CmdType = grd.Cell(idx, ColNames.CommandType).Text '获取cmdType’ gRowNodeInfo(idx).RowIdx = idx gRowNodeInfo(idx).IsRecord = grd.Cell(idx, ColNames.SaveToDb).BooleanValue gRowNodeInfo(idx).Description = grd.Cell(idx, ColNames.Description).Text gRowNodeInfo(idx).RecordName = grd.Cell(idx, ColNames.RecordName).Text 'gRowNodeInfo(idx).FatherNodeIdxLst.Clear() Next idx End Sub Private Function GetRowNodeAction(node As RowNode) As Boolean If node.ParentNode.RowLever <= 1 Then Return node.ParentNode.Action Else If node.ParentNode.Action Then Return GetRowNodeAction(node.ParentNode) Else Return False End If End If End Function Private Function GetRowNodeForeColor(node As RowNode) As Color If node.Action Then If node.RowLever > 1 AndAlso GetRowNodeAction(node) = False Then Return Color.LightGray Select Case node.RowType Case RowNode.RowTypeEnum.Flow Select Case node.CommandType Case "System" If node.Command = "Call" Then Return Color.Blue Else Return Color.DarkSlateGray End If Case "ComPort" Return Color.DarkCyan Case "UtsComPort" Return Color.SeaGreen Case "Converter" Return Color.DarkOrange Case "Process" Return Color.DarkBlue Case Else Return Color.Black End Select Case RowNode.RowTypeEnum.Module Return Color.DeepPink Case RowNode.RowTypeEnum.FixedModule Return Color.Blue Case Else Return Color.Black End Select Else Return Color.LightGray End If End Function ''' ''' 节点状态变更,修改节点行颜色 ''' ''' Private Sub NodeActionChanged(node As RowNode) Dim row As Integer = node.RowListIndex Dim tmpRowColor As Color LockGridAutoRedraw() tmpRowColor = GetRowNodeForeColor(node) '获取选颜色 _grd.Range(row, ColNames.Result, row, ColNames.ErrorMessage).ForeColor = tmpRowColor '着色 If node.SaveToDb = False Then _grd.Cell(row, ColNames.RecordName).ForeColor = Color.LightGray '着色 End If If node.CommandType = "" And node.Description = "" Then '空白行字体与底色同色,避免对编辑产生干扰 _grd.Range(row, ColNames.Result, row, ColNames.ErrorMessage).ForeColor = _grd.Cell(row, ColNames.Description).BackColor '着色 End If If node.RowType = RowNode.RowTypeEnum.FixedModule Then _grd.Range(row, ColNames.CommandType, row, ColNames.ErrorMessage).ForeColor = _grd.Cell(row, ColNames.Description).BackColor '着色 End If For i As Integer = 0 To node.RowNodes.Count - 1 NodeActionChanged(CType(node.RowNodes(i), RowNode), node.Action) Next UnLockGridAutoRedraw() End Sub ''' ''' 节点状态变更,修改节点行颜色 ''' ''' Private Sub NodeActionChanged(node As RowNode, action As Boolean) Dim row As Integer = node.RowListIndex Dim tmpRowColor As Color tmpRowColor = GetRowNodeForeColor(node) '获取选颜色 _grd.Range(row, ColNames.Result, row, ColNames.ErrorMessage).ForeColor = tmpRowColor '着色 If node.SaveToDb = False Then _grd.Cell(row, ColNames.RecordName).ForeColor = Color.LightGray '着色 End If If node.CommandType = "" And node.Description = "" Then '空白行字体与底色同色,避免对编辑产生干扰 _grd.Range(row, ColNames.Result, row, ColNames.ErrorMessage).ForeColor = _grd.Cell(row, ColNames.Description).BackColor '着色 End If If node.RowType = RowNode.RowTypeEnum.FixedModule Then _grd.Range(row, ColNames.CommandType, row, ColNames.ErrorMessage).ForeColor = _grd.Cell(row, ColNames.Description).BackColor '着色 End If For i As Integer = 0 To node.RowNodes.Count - 1 NodeActionChanged(CType(node.RowNodes(i), RowNode), action) Next End Sub ''' ''' 选定行使能或清除Action选项 ''' Public Sub Check_Uncheck_Action(grd As Grid, startRow As Integer, endRow As Integer, IsCheck As Boolean) Dim idx As Integer If endRow < startRow Then Return For idx = startRow To endRow grd.Cell(idx, ColNames.Action).Text = IsCheck.ToString Next End Sub ''' ''' 更新表格内容到缓存,但是并不重新着色 ''' Public Sub Call_UpdateGridActionInfo() UpdateGridActionInfo(_grd) End Sub ''' ''' 更新ActionEn信息 ''' Public Sub UpdateGridActionInfo(grd As Grid) If grd.EditorVisible Then Return '处于编辑状态 Dim idx As Integer Dim tmpRowType As Integer Dim tmpRowLevel As Integer Dim tmpRowIdx As Integer Dim tmpActionEn As Boolean Dim currRowCmdType As String If gIsGri_UpdateGridActionInfo_EventReady = True Then gIsGri_UpdateGridActionInfo_EventReady = False UpdateGridInfo(grd) '根据遍历数据,重新确认每一行的ActiveEn值 For idx = 1 To grd.Rows - 1 'For idx = startRowIdx To endRowNodeIdx currRowCmdType = gRowNodeInfo(idx).CmdType tmpRowLevel = gRowNodeInfo(idx).NodeLevel tmpRowType = gRowNodeInfo(idx).NodeType tmpActionEn = gRowNodeInfo(idx).ActionVal tmpRowIdx = idx 'gRowNodeInfo(idx).FatherNodeIdxLst.Add(idx) If gRowNodeInfo(idx).ActionVal = False Then '如果本行Action = false,则免去遍历,直接给false gRowNodeInfo(idx).ActionEn = False Else '如果本机为Active val = true,就继续遍历父级节点 Select Case tmpRowType Case > 0 If tmpRowLevel > 1 Then Do tmpRowIdx = tmpRowIdx - 1 '往上一行 tmpRowType = gRowNodeInfo(tmpRowIdx).NodeType '该行的RowType If tmpRowType = RowNode.RowTypeEnum.Module Then '找到Module If gRowNodeInfo(tmpRowIdx).NodeLevel = tmpRowLevel - 1 Then '第一个上一级节点就是自己的亲生父亲 tmpRowLevel = gRowNodeInfo(tmpRowIdx).NodeLevel '更新节点级别 tmpActionEn = tmpActionEn And gRowNodeInfo(tmpRowIdx).ActionVal '将父节点的Action状态运算进来’ 'gRowNodeInfo(idx).FatherNodeIdxLst.Add(tmpRowIdx) '将父级节点添加到链表 End If End If '一直遍历直到一级父节点,或者达到表格顶端,或者检查到False的父节点就退出遍历 Loop Until tmpRowLevel = 1 Or tmpRowIdx <= 1 Or tmpActionEn = False gRowNodeInfo(idx).ActionEn = tmpActionEn Else '==1 gRowNodeInfo(idx).ActionEn = gRowNodeInfo(idx).ActionVal End If Case RowNode.RowTypeEnum.FixedModule gRowNodeInfo(idx).ActionEn = gRowNodeInfo(idx).ActionVal End Select End If Next idx gIsGri_UpdateGridActionInfo_EventReady = True End If End Sub Private Sub Grid_EnterRow(Sender As Object, e As Grid.EnterRowEventArgs) End Sub ''' ''' 光标移动时,所在行底色高亮 ''' Private Sub Grid_MouseMove(Sender As Object, e As MouseEventArgs) If _grd.EditorVisible Then Return '处于编辑状态 If gIsGri_MouseMove_EventReady = True Then Dim tmpMouseRow As Integer = _grd.MouseRow '鼠标当前行’ Dim tmpMouseCol As Integer = _grd.MouseCol '鼠标当前列’ If tmpMouseRow <= 0 Or tmpMouseCol <= 0 Then Return 'Dim tmpMouseRowNodeIdx As Integer = gRowNodeInfo(tmpMouseRow).RowIdx 'GetRowNodeIdx(_grd, tmpMouseRow) '同级节点计数’ 'Dim tmpMouseRowNodeLevel As Integer = gRowNodeInfo(tmpMouseRow).NodeLevel 'GetRowNodeLevel(_grd, tmpMouseRow) '节点级数 'Dim tmpMouseRowNodeLstIdx As Integer = gRowNodeInfo(tmpMouseRow).NodeIdx 'GetRowNodeLstIdx(_grd, tmpMouseRow) '就是行号 'gRowType = gRowNodeInfo(tmpMouseRow).NodeType 'GetRowType(_grd, tmpMouseRow) '现在所在行的row type 'gOldRowType = gRowNodeInfo(gMouseOldRow).NodeType 'GetRowType(_grd, gMouseOldRow) '前一次的row type Dim tmpMouseRowNodeIdx As Integer = GetRowNodeIdx(_grd, tmpMouseRow) '同级节点计数’ Dim tmpMouseRowNodeLevel As Integer = GetRowNodeLevel(_grd, tmpMouseRow) '节点级数 Dim tmpMouseRowNodeLstIdx As Integer = GetRowNodeLstIdx(_grd, tmpMouseRow) '就是行号 gRowType = GetRowType(_grd, tmpMouseRow) '现在所在行的row type gOldRowType = GetRowType(_grd, gMouseOldRow) '前一次的row type Try If tmpMouseRow <> gMouseOldRow Or tmpMouseCol <> gMouseOldCol Then '鼠标所在行变化 If gOldRowType <> RowNode.RowTypeEnum.FixedModule Then '光标离开Flow节点 _grd.Range(gMouseOldRow, ColNames.Result, gMouseOldRow, ColNames.ErrorMessage).BackColor = Color.White _grd.Cell(gMouseOldRow, gMouseOldCol).FontBold = False If gOldRowType = RowNode.RowTypeEnum.Module And gMouseOldCol = ColNames.Description Then '光标离开Module节点 Mouse_MoveOnNode_BackColorRepain(_grd, gOldRowType, gMouseOldRow, Color.White) End If End If gMouseOldRow = tmpMouseRow gMouseOldCol = tmpMouseCol Else If gRowType <> RowNode.RowTypeEnum.FixedModule Then '光标移动到flow节点 _grd.Range(tmpMouseRow, ColNames.Result, tmpMouseRow, ColNames.ErrorMessage).BackColor = Color.LemonChiffon '_grd.Cell(_grd.MouseRow, _grd.MouseCol).FontBold = True _grd.Cell(tmpMouseRow, tmpMouseCol).FontBold = True If gRowType = RowNode.RowTypeEnum.Module And tmpMouseCol = ColNames.Description Then '光标移动到module节点 Mouse_MoveOnNode_BackColorRepain(_grd, gRowType, tmpMouseRow, Color.LemonChiffon) End If End If End If Catch ex As Exception gIsGri_MouseMove_EventReady = True End Try End If gIsGri_MouseMove_EventReady = True End Sub ''' ''' 获取指定行的NodeIndex ''' ''' Public Function GetRowNodeLstIdx(grd As Grid, cellRow As Integer) As Integer Try Dim node As RowNode = _headNode.RowList(cellRow - _drawStartRow + 1) Return node.RowListIndex Catch ex As Exception Return 0 End Try End Function ''' ''' 获取指定行的NodeLever ''' ''' Public Function GetRowNodeLevel(grd As Grid, cellRow As Integer) As Integer Try Dim node As RowNode = _headNode.RowList(cellRow - _drawStartRow + 1) Return node.RowLever Catch ex As Exception Return 0 End Try End Function ''' ''' 获取指定行的NodeIndex ''' ''' Public Function GetRowNodeIdx(grd As Grid, cellRow As Integer) As Integer Try Dim node As RowNode = _headNode.RowList(cellRow - _drawStartRow + 1) Return node.RowIndex Catch ex As Exception Return 0 End Try End Function ''' ''' 获取指定行的RowType ''' ''' Public Function GetRowType(grd As Grid, cellRow As Integer) As Integer Try Dim node As RowNode = _headNode.RowList(cellRow - _drawStartRow + 1) Return node.RowType Catch ex As Exception Return 3 End Try End Function Property HeadNode() As RowNode Get Return _headNode End Get Set(value As RowNode) _headNode = value End Set End Property ''' ''' 折叠的列号 ''' ''' Property NodeCol() As Integer Get Return _drawCol End Get Set(value As Integer) _drawCol = value End Set End Property ''' ''' 折叠的起始行号 ''' ''' Property NodeStartRow() As Integer Get Return _drawStartRow End Get Set(value As Integer) _drawStartRow = value End Set End Property ''' ''' 初始化测试站表格 ''' Public Sub InitializeGrid() With _grd LockGridAutoRedraw() .Rows = 1 .Cols = ColNames.Max .DrawMode = DrawModeEnum.OwnerDraw '绘制方式为自绘 .DisplayRowNumber = True '首列显示数字 .ExtendLastCol = True '最后一列自动扩充 '.MultiSelect = False '是否允许选择多行 .FrozenCols = ColNames.Description '冻结列 .BorderStyle = BorderStyleEnum.None .DefaultFont = New Font("微软雅黑", 8) '.DefaultFont = New Font("Consolas", 8) .Range(0, 0, 0, .Cols - 1).Font = New Font($"幼圆", 8) '首行样式 ' .SelectionMode = SelectionModeEnum.ByRow '选中一行 '.BackColor1 = Color.AliceBlue'单行背景色 '.BackColor2 = Color.Azure'双行背景色 .Tree.Row = 2 .Tree.Col = ColNames.Description .Tree.ShowLines = True .Tree.CheckBoxes = False .Tree.Nodes.Clear() For col As Integer = 0 To ColNames.Max - 1 Select Case col Case ColNames.Pause .Cell(0, col).Text = $"P" Case ColNames.Action .Cell(0, col).Text = $"A" Case ColNames.SaveToDb .Cell(0, col).Text = $"S" Case Else .Cell(0, col).Text = [Enum].GetName(GetType(ColNames), col) '设置列名 End Select Next '设置位宽 .Column(ColNames.Step).Width = 40 .Column(ColNames.Label).Width = 80 .Column(ColNames.Result).Width = 80 .Column(ColNames.LowerLimit).Width = 80 .Column(ColNames.UpperLimit).Width = 80 .Column(ColNames.TimeElapsed).Width = 80 .Column(ColNames.Pause).Width = 20 .Column(ColNames.Action).Width = 20 .Column(ColNames.Description).Width = 200 .Column(ColNames.ControlType).Width = 0 .Column(ColNames.CommandType).Width = 80 .Column(ColNames.Command).Width = 120 .Column(ColNames.Parameters).Width = 340 .Column(ColNames.SaveToDb).Width = 20 .Column(ColNames.RecordName).Width = 100 .Column(ColNames.Retry).Width = 40 .Column(ColNames.RetryInterval).Width = 40 .Column(ColNames.ErrorCode).Width = 100 '设置类型 .Column(ColNames.Pause).CellType = CellTypeEnum.CheckBox .Column(ColNames.Action).CellType = CellTypeEnum.CheckBox .Column(ColNames.SaveToDb).CellType = CellTypeEnum.CheckBox .Column(ColNames.ControlType).CellType = CellTypeEnum.ComboBox .Column(ColNames.CommandType).CellType = CellTypeEnum.ComboBox .Column(ColNames.Command).CellType = CellTypeEnum.ComboBox .Column(ColNames.ErrorCode).CellType = CellTypeEnum.ComboBox .ComboBox(ColNames.ControlType).Locked = True .ComboBox(ColNames.CommandType).Locked = True .ComboBox(ColNames.Command).Locked = True .ComboBox(ColNames.ErrorCode).Locked = True '格栅颜色 .GridColor = Color.WhiteSmoke '可见度 UpdateColVisible() '对齐方式 UpdateColAlignment() UnLockGridAutoRedraw() End With End Sub Private Sub UpdateColAlignment() With _grd .Column(ColNames.Step).Alignment = AlignmentEnum.CenterCenter .Column(ColNames.Label).Alignment = AlignmentEnum.RightCenter .Column(ColNames.Pause).Alignment = AlignmentEnum.CenterCenter .Column(ColNames.Action).Alignment = AlignmentEnum.CenterCenter .Column(ColNames.Description).Alignment = AlignmentEnum.LeftCenter .Column(ColNames.ControlType).Alignment = AlignmentEnum.LeftCenter .Column(ColNames.CommandType).Alignment = AlignmentEnum.LeftCenter .Column(ColNames.Command).Alignment = AlignmentEnum.LeftCenter .Column(ColNames.Parameters).Alignment = AlignmentEnum.LeftCenter .Column(ColNames.SaveToDb).Alignment = AlignmentEnum.CenterCenter .Column(ColNames.RecordName).Alignment = AlignmentEnum.LeftCenter .Column(ColNames.Retry).Alignment = AlignmentEnum.RightCenter .Column(ColNames.RetryInterval).Alignment = AlignmentEnum.RightCenter .Column(ColNames.ErrorCode).Alignment = AlignmentEnum.RightCenter End With End Sub Private Sub UpdateColVisible() With _grd .Column(ColNames.Pause).Visible = _debugMode .Column(ColNames.Result).Visible = _debugMode .Column(ColNames.LowerLimit).Visible = _debugMode .Column(ColNames.UpperLimit).Visible = _debugMode .Column(ColNames.TimeElapsed).Visible = _debugMode End With End Sub Private Function ParamsToString(params As List(Of TestCmdParam)) As String Dim result As New StringBuilder For i As Integer = 0 To params.Count - 1 If i = 0 Then result.Append(params(i).Value) Else result.Append($" {_paramChar} {params(i).Value}") End If Next Return result.ToString() End Function Public Sub UpdateGrid(grd As Grid, row As Integer, node As RowNode) Dim rowCmdType As String Dim tmpIsAction As Boolean Dim tmpColor As Color With grd .Cell(row, ColNames.Pause).Text = IIf(node.Pause, "1", "0").ToString() .Cell(row, ColNames.Action).Text = IIf(node.Action, "1", "0").ToString() .Cell(row, ColNames.Label).Text = $"{node.Label}" .Cell(row, ColNames.Description).Text = $"{node.Description}" .Cell(row, ColNames.ControlType).Text = node.ControlType .Cell(row, ColNames.CommandType).Text = $"{node.CommandType}" .Cell(row, ColNames.Command).Text = $"{node.Command}" .Cell(row, ColNames.Parameters).Text = $"{ParamsToString(node.Parameters)}" .Cell(row, ColNames.SaveToDb).Text = $"{node.SaveToDb}" .Cell(row, ColNames.RecordName).Text = $"{node.RecordName}" .Cell(row, ColNames.Retry).Text = $"{node.Retry}" .Cell(row, ColNames.RetryInterval).Text = $"{node.RetryInterval}" .Cell(row, ColNames.ErrorCode).Text = $"{node.ErrorCode}" .Cell(row, ColNames.ErrorMessage).Text = $"{node.ErrorMessage}" rowCmdType = .Cell(row, ColNames.CommandType).Text tmpIsAction = .Cell(row, ColNames.Action).BooleanValue 'tmpColor = setRowTextForeColor(rowCmdType, tmpIsAction, node.RowType) tmpColor = GetRowNodeForeColor(node) If node.RowType = RowNode.RowTypeEnum.FixedModule Then .Range(row, ColNames.Result, row, ColNames.ErrorMessage).FontSize = 10 .Range(row, ColNames.Result, row, ColNames.ErrorMessage).BackColor = Color.PeachPuff .Range(row, ColNames.Result, row, ColNames.ErrorMessage).ForeColor = Color.Blue .Range(row, ColNames.Result, row, ColNames.ErrorMessage).FontBold = True .Range(row, ColNames.Result, row, ColNames.ErrorMessage).Locked = True ElseIf node.RowType = RowNode.RowTypeEnum.Module Then If .Cell(row, ColNames.Action).BooleanValue = True Then .Range(row, ColNames.Result, row, ColNames.ErrorMessage).ForeColor = Color.DeepPink Else .Range(row, ColNames.Result, row, ColNames.ErrorMessage).ForeColor = Color.LightGray End If .Range(row, ColNames.Result, row, ColNames.ErrorMessage).FontSize = 8 .Range(row, ColNames.Result, row, ColNames.ErrorMessage).FontBold = False .Range(row, ColNames.Result, row, ColNames.ErrorMessage).Locked = False Else .Range(row, ColNames.Result, row, ColNames.ErrorMessage).ForeColor = tmpColor .Range(row, ColNames.Result, row, ColNames.ErrorMessage).Locked = False End If End With End Sub Public Sub UpdateGrid(grd As Grid, nodes As RowNodeCollection) For Each node As RowNode In nodes grd.AddItem(node.RowLever, node.Description, String.Empty) Dim row As Integer = grd.Rows - 1 UpdateGrid(grd, row, node) If node.RowNodes.Count > 0 Then UpdateGrid(grd, node.RowNodes) End If Next End Sub Public Sub UpdateGrid() _uploading = True InitializeGrid() With _grd LockGridAutoRedraw() UpdateGrid(_grd, _headNode.RowNodes) UnLockGridAutoRedraw() End With _uploading = False End Sub #Region "表格事件" Public Sub Grid_OwnerDrawCell(ByVal sender As Object, ByVal e As Grid.OwnerDrawCellEventArgs) If e.Row < NodeStartRow OrElse e.Col <> _drawCol Then Return Dim intWidth As Integer Dim intAdd As Integer If _showNodeIcon Then intWidth = 20 intAdd = 26 Else intWidth = 10 intAdd = 6 End If If _headNode Is Nothing Then Return Dim node As RowNode = _headNode.RowList(e.Row - _drawStartRow + 1) If node Is Nothing Then Return '画树线 Dim pen As New Pen(Color.Gray, 1) With {.DashStyle = Drawing2D.DashStyle.Solid} Dim drawLine As Boolean Dim intLevel As Integer = node.RowLever Dim tmpNode As RowNode For i As Integer = 0 To intLevel If i < intLevel - 1 Then '父级的父级 drawLine = True tmpNode = node For j As Integer = i To intLevel - 2 tmpNode = tmpNode.ParentNode Next If tmpNode.NextNode Is Nothing Then drawLine = False End If If drawLine Then '全部 e.Graphics.DrawLine(pen, CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Top - 1), CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Bottom + 1)) End If ElseIf i = intLevel - 1 Then '父级 '上半部分 e.Graphics.DrawLine(pen, CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Top - 1), CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Top + e.Bounds.Height / 2)) If node.NextNode IsNot Nothing Then '下半部分 e.Graphics.DrawLine(pen, CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Top + e.Bounds.Height / 2), CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Bottom + 1)) End If ElseIf i = intLevel Then '同级 '下半部分 If node.Expanded AndAlso node.Count > 0 Then If _showNodeIcon Then e.Graphics.DrawLine(pen, CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Top + e.Bounds.Height / 2) + 7, CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Bottom + 1)) Else e.Graphics.DrawLine(pen, CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Top + e.Bounds.Height / 2), CInt(e.Bounds.Left + intWidth * i + intAdd), CInt(e.Bounds.Bottom + 1)) End If End If End If '水平的 If intLevel > 0 Then If String.IsNullOrEmpty(_grd.Cell(e.Row, ColNames.Description).Text) Then If node.NextNode Is Nothing Then e.Graphics.DrawLine(pen, CInt(e.Bounds.Left + intWidth * (intLevel - 1) + intAdd), CInt(e.Bounds.Top + e.Bounds.Height / 2), CInt(e.Bounds.Left + intWidth * (intLevel - 1) + intAdd + 10), CInt(e.Bounds.Top + e.Bounds.Height / 2)) End If _grd.Cell(e.Row, ColNames.Action).CellType = CellTypeEnum.TextBox _grd.Cell(e.Row, ColNames.Action).Text = "" Else e.Graphics.DrawLine(pen, CInt(e.Bounds.Left + intWidth * (intLevel - 1) + intAdd), CInt(e.Bounds.Top + e.Bounds.Height / 2), CInt(e.Bounds.Left + intWidth * (intLevel - 1) + intAdd + 10), CInt(e.Bounds.Top + e.Bounds.Height / 2)) _grd.Cell(e.Row, ColNames.Action).CellType = CellTypeEnum.CheckBox End If End If Next pen.Dispose() '+/- If node.RowNodes.Count > 0 Then Dim rect As New Rectangle(e.Bounds.Left + 2 + intLevel * intWidth, CInt(e.Bounds.Top + (e.Bounds.Height - 9) / 2), 8, 8) e.Graphics.FillRectangle(Brushes.White, rect) e.Graphics.DrawRectangle(Pens.Black, rect) If node.Expanded Then e.Graphics.DrawLine(Pens.Black, rect.Left + 2, rect.Top + 4, rect.Right - 2, rect.Top + 4) Else e.Graphics.DrawLine(Pens.Black, rect.Left + 2, rect.Top + 4, rect.Right - 2, rect.Top + 4) e.Graphics.DrawLine(Pens.Black, rect.Left + 4, rect.Top + 2, rect.Left + 4, rect.Bottom - 2) End If End If '文字 Dim bColor As New SolidBrush(_grd.Cell(e.Row, e.Col).ForeColor) With _grd.Cell(e.Row, e.Col) If _showNodeIcon Then e.Graphics.DrawString(.Text, .Font, bColor, e.Bounds.Left + intWidth * intLevel + 35, e.Bounds.Top + (e.Bounds.Height - e.Graphics.MeasureString(.Text, .Font).Height) / 2 + 1) Else e.Graphics.DrawString(.Text, .Font, bColor, e.Bounds.Left + intWidth * intLevel + 12, e.Bounds.Top + (e.Bounds.Height - e.Graphics.MeasureString(.Text, .Font).Height) / 2 + 1) End If End With e.Handled = True End Sub Private Sub Grid_Click(ByVal sender As Object, ByVal e As EventArgs) If _grd.EditorVisible Then Return '处于编辑状态 Dim point As Point = _grd.PointToClient(Windows.Forms.Cursor.Position) Dim cel As Cell = _grd.HitTest(point.X, point.Y) If cel Is Nothing Then Return If cel.Row < _drawStartRow OrElse cel.Col <> _drawCol Then Return If _headNode Is Nothing Then Return Dim node As RowNode = _headNode.RowList(cel.Row - _drawStartRow + 1) If node Is Nothing Then Return Dim intWidth As Integer = CInt(IIf(_showNodeIcon, 20, 10)) Dim rect As New Rectangle(cel.Bounds.Left + 2 + node.RowLever * intWidth, cel.Bounds.Top + ((cel.Bounds.Height - 9) \ 2), 8, 8) If rect.Contains(point) = False Then Return If node.Expanded Then node.Collapse() LockGridAutoRedraw() For i As Integer = 1 To node.AllChildCount _grd.Row(node.RowListIndex + i).Visible = False Next UnLockGridAutoRedraw() Else node.Expand() LockGridAutoRedraw() ExpandRows(node) UnLockGridAutoRedraw() End If End Sub ''' ''' 展开行节点 ''' ''' Public Sub ExpandRows(node As RowNode) For Each child As RowNode In node.Children _grd.Row(child.RowListIndex).Visible = True '如果子节点上一次为收缩的,则展开依旧为收缩的 If child.Children.Count <= 0 Then Continue For If child.Expanded Then ExpandRows(child) Next End Sub Private Sub CommandChanged(node As RowNode) _grd.Cell(node.RowListIndex, ColNames.Parameters).Text = ParamsToString(node.Parameters) _grd.Cell(node.RowListIndex, ColNames.Action).Text = IIf(node.Action, "1", "0").ToString End Sub Private Sub CommandTypeChanged(node As RowNode) _grd.Cell(node.RowListIndex, ColNames.Command).Text = " " _grd.Cell(node.RowListIndex, ColNames.Parameters).Text = ParamsToString(node.Parameters) End Sub Private Sub ErrCodeChanged(node As RowNode) _grd.Cell(node.RowListIndex, ColNames.ErrorMessage).Text = node.ErrorMessage End Sub Private Sub UpdateNode_ActionChanged(node As RowNode) If node.IsRunning Then For i As Integer = 0 To node.RowNodes.Count - 1 node.Children(i).IsRunning = node.Children(i).Action UpdateNode_ActionChanged(node.Children(i)) Next Else For i As Integer = 0 To node.RowNodes.Count - 1 node.Children(i).IsRunning = node.IsRunning UpdateNode_ActionChanged(node.Children(i)) Next End If End Sub Private Sub Grid_CellChange(sender As Object, e As Grid.CellChangeEventArgs) If _uploading Then Return If _headNode Is Nothing Then Return Dim node As RowNode = _headNode.RowList(e.Row - _drawStartRow + 1) If node Is Nothing Then Return Dim changeType As RowNodeChangedEventArgs.RowNodeChangeType changeType = RowNodeChangedEventArgs.RowNodeChangeType.None Select Case e.Col Case ColNames.[Pause] node.[Pause] = _grd.Cell(e.Row, e.Col).BooleanValue If node.[Pause] Then _grd.Cell(e.Row, e.Col).BackColor = Color.Red Else _grd.Cell(e.Row, e.Col).BackColor = Color.White End If Case ColNames.Action node.Action = _grd.Cell(e.Row, e.Col).BooleanValue changeType = RowNodeChangedEventArgs.RowNodeChangeType.Action If node.RowType = RowNode.RowTypeEnum.FixedModule Then _grd.Cell(e.Row, e.Col).Text = "1" node.Action = _grd.Cell(e.Row, e.Col).BooleanValue End If NodeActionChanged(node) Case ColNames.Description node.Description = _grd.Cell(e.Row, e.Col).Text changeType = RowNodeChangedEventArgs.RowNodeChangeType.Description Case ColNames.[Label] node.Label = _grd.Cell(e.Row, e.Col).Text If String.IsNullOrWhiteSpace(node.Label) Then node.RowType = RowNode.RowTypeEnum.Flow Else node.RowType = RowNode.RowTypeEnum.Module End If changeType = RowNodeChangedEventArgs.RowNodeChangeType.Label Case ColNames.ControlType node.ControlType = _grd.Cell(e.Row, e.Col).Text If String.IsNullOrWhiteSpace(node.ControlType) Then node.RowType = RowNode.RowTypeEnum.Flow Else node.RowType = RowNode.RowTypeEnum.Control End If changeType = RowNodeChangedEventArgs.RowNodeChangeType.ControlType Case ColNames.CommandType If String.Compare(node.CommandType, _grd.Cell(e.Row, e.Col).Text) <> 0 Then node.CommandType = _grd.Cell(e.Row, e.Col).Text node.Command = "" node.Parameters.Clear() CommandTypeChanged(node) changeType = RowNodeChangedEventArgs.RowNodeChangeType.CommandType End If 'NodeAction_Change(_grd, node.RowType, e.Row, node.Action) NodeActionChanged(node) Case ColNames.Command If node.Command <> _grd.Cell(e.Row, e.Col).Text Then node.Command = _grd.Cell(e.Row, e.Col).Text If String.IsNullOrWhiteSpace(node.Command) Then node.Action = False Else node.Action = True End If node.Parameters.Clear() '拷贝所有参数到当前节点信息中 Dim planCommand As TestCmd = _testCmdManager.GetCommand(node.CommandType, node.Command) If planCommand Is Nothing Then Return For Each cmdParam As TestCmdParam In planCommand.Params node.Parameters.Add(cmdParam.Clone()) Next CommandChanged(node) changeType = RowNodeChangedEventArgs.RowNodeChangeType.Command End If Case ColNames.Parameters Dim str() As String = _grd.Cell(e.Row, e.Col).Text.Split(New Char() {_paramChar}) For i As Integer = 0 To node.Parameters.Count - 1 If i < str.Length Then node.Parameters(i).Value = str(i).Trim() Else node.Parameters(i).Value = String.Empty End If Next changeType = RowNodeChangedEventArgs.RowNodeChangeType.Parameters Case ColNames.SaveToDb node.SaveToDb = _grd.Cell(e.Row, e.Col).BooleanValue changeType = RowNodeChangedEventArgs.RowNodeChangeType.SaveToDb If node.RowType = RowNode.RowTypeEnum.FixedModule Then _grd.Cell(e.Row, e.Col).Text = "0" End If ' NodeAction_Change(_grd, node.RowType, e.Row, node.Action) NodeActionChanged(node) Case ColNames.RecordName node.RecordName = _grd.Cell(e.Row, e.Col).Text changeType = RowNodeChangedEventArgs.RowNodeChangeType.RecordName 'CheckRecordName_Duplicate(_grd) '确认记录名称是否有重名项 Case ColNames.Retry node.Retry = _grd.Cell(e.Row, e.Col).IntegerValue changeType = RowNodeChangedEventArgs.RowNodeChangeType.Retry Case ColNames.RetryInterval node.RetryInterval = _grd.Cell(e.Row, e.Col).IntegerValue changeType = RowNodeChangedEventArgs.RowNodeChangeType.RetryInterval Case ColNames.ErrorCode node.ErrorCode = _grd.Cell(e.Row, e.Col).Text changeType = RowNodeChangedEventArgs.RowNodeChangeType.ErrorCode Case ColNames.ErrorMessage node.ErrorMessage = _grd.Cell(e.Row, e.Col).Text changeType = RowNodeChangedEventArgs.RowNodeChangeType.ErrorMessage End Select '触发事件 If SkipEvent Then Return Select Case changeType Case RowNodeChangedEventArgs.RowNodeChangeType.None Return End Select StationEditStatusMonitor.StationEditStatus = StationEditStatusMonitor.StationEditStatusEnum.Changed Dim args As New RowNodeChangedEventArgs With { .Node = node, .ChangeType = changeType } RaiseEvent RowNodeTextChanged(sender, args) End Sub Private Sub Grid_SelChange(sender As Object, e As Grid.SelChangeEventArgs) 'todo:更新详情表格 If _headNode Is Nothing Then Return Dim node As RowNode = _headNode.RowList(_grd.ActiveCell.Row - _drawStartRow + 1) If node Is Nothing Then Return ActiveNode = node Dim LineNumber As Integer = e.FirstRow Dim LineActionEn As Boolean = node.Action '触发事件 If SkipEvent Then Return Dim event2 As New PlanNodeSelectChangedEventArgs With {.Node = node, .LineNumber = LineNumber, .LineActionEn = LineActionEn } RaiseEvent PlanNodeSelectChanged(sender, event2) End Sub Private _dropCol As Integer = 0 Private _dropRow As Integer = 0 Private Sub Grid_ComboDropDown(sender As Object, e As Grid.ComboDropDownEventArgs) _dropRow = e.Row _dropCol = e.Col Select Case e.Col Case ColNames.Command _grd.ComboBox(ColNames.Command).Items.Clear() If _testCmdManager Is Nothing Then Return Dim type As String = _grd.Cell(e.Row, ColNames.CommandType).Text _grd.ComboBox(ColNames.Command).Items.AddRange(_testCmdManager.GetCommandNames(type)) Case ColNames.ControlType _grd.ComboBox(ColNames.ControlType).Items.Clear() If ActiveNode.ParentNode.ControlType = "If" Then _grd.ComboBox(ColNames.ControlType).Items.Add("Then") _grd.ComboBox(ColNames.ControlType).Items.Add("ElseIf") _grd.ComboBox(ColNames.ControlType).Items.Add("Else") Else _grd.ComboBox(ColNames.ControlType).Items.Add("") _grd.ComboBox(ColNames.ControlType).Items.Add("If") _grd.ComboBox(ColNames.ControlType).Items.Add("While") End If End Select End Sub Private Sub Grid_ComboClick(sender As Object, e As Grid.ComboClickEventArgs) Select Case _dropCol Case ColNames.ErrorCode Dim codeMsg As String = _grd.Cell(_dropRow, ColNames.ErrorCode).Text Dim errCode As String = ErrCodeManager.CodeMsgToCode(codeMsg) If String.Compare(ActiveNode.ErrorCode, errCode) <> 0 Then ActiveNode.ErrorCode = errCode ActiveNode.ErrorMessage = _errCodeManager(ActiveNode.ErrorCode).Msg _grd.Cell(ActiveNode.RowListIndex, ColNames.ErrorCode).Text = ActiveNode.ErrorCode _grd.Cell(ActiveNode.RowListIndex, ColNames.ErrorCode).BackColor = _errCodeManager(ActiveNode.ErrorCode).Color _grd.Cell(ActiveNode.RowListIndex, ColNames.ErrorMessage).BackColor = _grd.Cell(ActiveNode.RowListIndex, ColNames.ErrorCode).BackColor ErrCodeChanged(ActiveNode) End If End Select End Sub #End Region #Region "表格操作" Public Sub SetNodeActionShowMode(action As Boolean) If _headNode Is Nothing Then Return LockGridAutoRedraw() For i As Integer = 0 To _headNode.RowList.Count - 1 If _headNode.RowList(i).RowType = RowNode.RowTypeEnum.FixedModule Then _grd.Row(i).Visible = True ElseIf _headNode.RowList(i).RowType = RowNode.RowTypeEnum.Module Then If action = False Then _grd.Row(i).Visible = True Else If _headNode.RowList(i).Action Then _grd.Row(i).Visible = True Else _grd.Row(i).Visible = False For j As Integer = 1 To _headNode.RowList(i).AllChildCount _grd.Row(i + j).Visible = False Next i += _headNode.RowList(i).AllChildCount End If End If Else If action Then If _headNode.RowList(i).Action Then _grd.Row(i).Visible = True Else _grd.Row(i).Visible = False End If Else _grd.Row(i).Visible = True End If End If Next UnLockGridAutoRedraw() End Sub Public Sub SetNodeRecordShowMode(recode As Boolean) If _headNode Is Nothing Then Return ' _grd.AutoRedraw = False LockGridAutoRedraw() For i As Integer = 0 To _headNode.RowList.Count - 1 If _headNode.RowList(i).RowType = RowNode.RowTypeEnum.FixedModule Then _grd.Row(i).Visible = True ElseIf _headNode.RowList(i).RowType = RowNode.RowTypeEnum.Module Then _grd.Row(i).Visible = Not recode Else If recode Then If _headNode.RowList(i).SaveToDb Then _grd.Row(i).Visible = True Else _grd.Row(i).Visible = False End If Else _grd.Row(i).Visible = True End If End If Next UnLockGridAutoRedraw() '_grd.AutoRedraw = True '_grd.Refresh() End Sub Public Sub SetNodeExpand(expand As Boolean) If _headNode Is Nothing Then Return LockGridAutoRedraw() For i As Integer = 1 To _headNode.RowList.Count - 1 If _headNode.RowList(i).RowType = RowNode.RowTypeEnum.FixedModule Then _grd.Row(i).Visible = True '隐藏Main节点的子节点 '_headNode.RowList(i).Expanded = expand 'For Each node As RowNode In _headNode.RowList(i).Children ' _grd.Row(node.RowListIndex).Visible = expand 'Next ElseIf _headNode.RowList(i).RowType = RowNode.RowTypeEnum.Module Then _headNode.RowList(i).Expanded = expand For Each node As RowNode In _headNode.RowList(i).Children _grd.Row(node.RowListIndex).Visible = expand 'If expand Then ' If String.IsNullOrEmpty(node.Description) AndAlso String.IsNullOrEmpty(node.CommandType) Then ' _grd.Row(node.RowListIndex).Visible = False ' Else ' _grd.Row(node.RowListIndex).Visible = True ' End If 'Else ' _grd.Row(node.RowListIndex).Visible = False 'End If Next Else If expand Then _grd.Row(i).Visible = True Else If String.IsNullOrEmpty(_headNode.RowList(i).Description) Then _grd.Row(i).Visible = expand End If End If End If Next UnLockGridAutoRedraw() End Sub Public Sub NodesAdd(childNode As RowNode) If _grd.ActiveCell Is Nothing Then Return If _headNode Is Nothing Then Return Dim node As RowNode = _headNode.RowList(_grd.ActiveCell.Row - _drawStartRow + 1) If node Is Nothing Then Return '更新内存 node.AddNode(childNode) '更新控件 NodesAdd2(childNode) End Sub Public Sub NodesAdd2(node As RowNode) If node.RowListIndex = _grd.Rows Then _grd.AddItem("") Else _grd.InsertRow(node.RowListIndex, 1) End If UpdateGrid(_grd, node.RowListIndex, node) If node.Children.Count > 0 Then For Each rowNode As RowNode In node.Children NodesAdd2(rowNode) Next End If End Sub Public Sub NodeAdd(rows As Integer) Dim idx As Integer Dim node As RowNode If rows < 1 Then Return If _grd.ActiveCell Is Nothing OrElse _grd.Tree.SelectedNode Is Nothing Then Return If _headNode Is Nothing Then Return LockGridAutoRedraw() Dim row As Integer = _grd.ActiveCell.Row + rows For idx = 1 To rows node = _headNode.RowList(_grd.ActiveCell.Row - _drawStartRow + 1) If node Is Nothing Then Exit For '更新内存 Dim rowNode As New RowNode With {.RowType = RowNode.RowTypeEnum.Flow} '在当前节点后插入节点 node.ParentNode.InsertNode(node.RowIndex, rowNode) '更新控件,若为最后一行,插入会失败 If _grd.Tree.SelectedNode.NextNode Is Nothing Then _grd.Tree.SelectedNode.Parent.Nodes.Add("", "") Else _grd.Tree.SelectedNode.Parent.Nodes.Insert(_grd.Tree.SelectedNode.Index, "") End If UpdateGrid(_grd, rowNode.RowListIndex, rowNode) Next idx '其他操作 _grd.Cell(row, _drawCol).SetFocus() UnLockGridAutoRedraw() End Sub Public Sub NodeDel(rows As Integer) Dim idx As Integer Dim node As RowNode If rows < 1 Then Return If _grd.ActiveCell Is Nothing OrElse _grd.Tree.SelectedNode Is Nothing Then Return If _headNode Is Nothing Then Return LockGridAutoRedraw() Dim row As Integer = _grd.ActiveCell.Row - 1 For idx = 1 To rows node = _headNode.RowList(_grd.ActiveCell.Row - _drawStartRow + 1) If node Is Nothing Then Exit For '更新内存 If node.CanDelete = False Then Exit For If node.RowType = RowNode.RowTypeEnum.Module Then If MessageBox.Show("删除节点将会导致所有子节点被连带删除!" & vbCrLf & "删除后不可恢复!" & vbCrLf & vbCrLf & "是否需要删除?", "删除节点", MessageBoxButtons.OKCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2) = DialogResult.Cancel Then Return End If node.Remove() '更新控件 _grd.Tree.SelectedNode.Remove() '其他操作 StationEditStatusMonitor.StationEditStatus = StationEditStatusMonitor.StationEditStatusEnum.Changed Next idx _grd.Cell(row, _drawCol).SetFocus() UnLockGridAutoRedraw() End Sub Public Sub NodeClear() If _grd.ActiveCell Is Nothing OrElse _grd.Tree.SelectedNode Is Nothing Then Return If _headNode Is Nothing Then Return Dim node As RowNode = _headNode.RowList(_grd.ActiveCell.Row - _drawStartRow + 1) If node Is Nothing Then Return '更新内存 Dim nodeCount As Integer = node.AllChildCount node.Clear() '更新控件 If nodeCount > 0 Then _grd.Tree.SelectedNode.Nodes.Clear() End If '其他操作 StationEditStatusMonitor.StationEditStatus = StationEditStatusMonitor.StationEditStatusEnum.Changed End Sub Public Sub NodeMoveUp(rows As Integer) Dim node As RowNode Dim moveDownRow As Integer '下移动前起始位置 Dim moveDownCount As Integer '下移动总量 Dim moveUpRow As Integer '上移动前起始位置 Dim moveUpCount As Integer '上移动总量 If rows < 1 Then Return If _grd.ActiveCell Is Nothing OrElse _grd.Tree.SelectedNode Is Nothing Then Return If _headNode Is Nothing Then Return node = _headNode.RowList(_grd.ActiveCell.Row - _drawStartRow + 1) If node Is Nothing Then Return '更新内存 If node.PrevNode Is Nothing Then Return moveDownRow = node.PrevNode.RowListIndex '下移动前起始位置 moveDownCount = node.PrevNode.AllChildCount + 1 '下移动总量 moveUpRow = node.RowListIndex '上移动前起始位置 moveUpCount = node.AllChildCount + 1 '上移动总量 node.MoveUp() UpdateGrid(_grd.Tree.SelectedNode.PrevNode, _grd.Tree.SelectedNode) _grd.Cell(node.RowListIndex, _grd.ActiveCell.Col).SetFocus() End Sub Public Sub NodeMoveDown() If _grd.ActiveCell Is Nothing OrElse _grd.Tree.SelectedNode Is Nothing Then Return If _headNode Is Nothing Then Return Dim node As RowNode = _headNode.RowList(_grd.ActiveCell.Row - _drawStartRow + 1) If node Is Nothing Then Return '更新内存 If node.NextNode Is Nothing Then Return Dim moveDownRow As Integer = node.RowListIndex '下移动前起始位置 Dim moveDownCount As Integer = node.AllChildCount + 1 '下移动总量 Dim moveUpRow As Integer = node.NextNode.RowListIndex '上移动前起始位置 Dim moveUpCount As Integer = node.NextNode.AllChildCount + 1 '上移动总量 node.MoveDown() UpdateGrid(_grd.Tree.SelectedNode, _grd.Tree.SelectedNode.NextNode) _grd.Cell(node.RowListIndex, _grd.ActiveCell.Col).SetFocus() End Sub Private Sub UpdateGrid(srcNode As FlexCell.Node, targetNode As FlexCell.Node) LockGridAutoRedraw() _uploading = True If srcNode.ChildCount >= targetNode.ChildCount Then targetNode.Remove() srcNode.Parent.Nodes.Insert(srcNode.Index, String.Empty) Dim node As RowNode = _headNode.RowList(srcNode.PrevNode.Row) UpdateGrid(_grd, node.RowListIndex, node) '获取表格节点,添加其子节点 Dim pNode As FlexCell.Node = _grd.Tree.FindNode(node.RowListIndex) AddGridTreeNode(pNode, node) Else srcNode.Remove() targetNode.Parent.Nodes.Insert(targetNode.Index + 1, String.Empty) Dim node As RowNode = _headNode.RowList(targetNode.NextNode.Row) UpdateGrid(_grd, node.RowListIndex, node) '获取表格节点,添加其子节点 Dim pNode As FlexCell.Node = _grd.Tree.FindNode(node.RowListIndex) AddGridTreeNode(pNode, node) End If '节点修改 StationEditStatusMonitor.StationEditStatus = StationEditStatusMonitor.StationEditStatusEnum.Changed _uploading = False UnLockGridAutoRedraw() End Sub Private Sub AddGridTreeNode(pNode As FlexCell.Node, srcNode As RowNode) For Each node As RowNode In srcNode.RowNodes pNode.Nodes.Insert(node.RowIndex, "") UpdateGrid(_grd, node.RowListIndex, node) AddGridTreeNode(_grd.Tree.FindNode(node.RowListIndex), node) Next End Sub Private Sub UpdateGrid(moveDownRow As Integer, moveDownCount As Integer, moveUpRow As Integer, moveUpCount As Integer) LockGridAutoRedraw() '更新控件 If moveUpCount < moveDownCount Then '表格行上移 For i As Integer = 0 To moveUpCount - 1 _grd.Row(moveUpRow + i).Position = moveDownRow + i Next Else '表格行下移 While moveDownCount > 0 _grd.Row(moveDownRow).Position = moveUpRow + moveUpCount - 1 moveDownCount -= 1 End While End If '节点修改 StationEditStatusMonitor.StationEditStatus = StationEditStatusMonitor.StationEditStatusEnum.Changed UnLockGridAutoRedraw() End Sub ''' ''' 节点升级 ''' Public Sub NodeMoveLeft(rows As Integer) Dim node As RowNode Dim moveDownRow As Integer '下移动前起始位置 Dim moveDownCount As Integer '下移动总量 Dim moveUpRow As Integer '上移动前起始位置 Dim moveUpCount As Integer '上移动总量 Dim nextNode As RowNode If rows < 1 Then Return If _grd.ActiveCell Is Nothing OrElse _grd.Tree.SelectedNode Is Nothing Then Return If _headNode Is Nothing Then Return Dim moveLeftSatrtRow As Integer = _grd.ActiveCell.Row Dim grdNode As FlexCell.Node Dim grdParentNode As FlexCell.Node LockGridAutoRedraw() _uploading = True For idx As Integer = 1 To rows node = _headNode.RowList(moveLeftSatrtRow - _drawStartRow + 1) Console.WriteLine($"Index:{node.RowListIndex}") If node Is Nothing Then Exit For If node.RowLever = 0 Then Exit For If node.RowType = RowNode.RowTypeEnum.FixedModule Then Exit For grdNode = _grd.Tree.FindNode(node.RowListIndex) grdParentNode = grdNode.Parent '更新内存 If node.NextNode Is Nothing Then node.MoveLeft() grdNode.Remove() grdParentNode.Parent.Nodes.Insert(grdParentNode.Index + 1, "") UpdateGrid(_grd, node.RowListIndex, node) AddGridTreeNode(_grd.Tree.FindNode(node.RowListIndex), node) Exit For End If moveDownRow = node.RowListIndex '下移动前起始位置 moveDownCount = node.AllChildCount + 1 '下移动总量 moveUpRow = node.NextNode.RowListIndex '上移动前起始位置 moveUpCount = 0 '上移动总量 nextNode = node.NextNode While nextNode IsNot Nothing moveUpCount += nextNode.AllChildCount + 1 nextNode = nextNode.NextNode End While node.MoveLeft() Console.WriteLine($"Node:{node.RowLever}") grdNode.Remove() grdParentNode.Parent.Nodes.Insert(grdParentNode.Index + 1, "") UpdateGrid(_grd, node.RowListIndex, node) AddGridTreeNode(_grd.Tree.FindNode(node.RowListIndex), node) _grd.Cell(node.RowListIndex, _grd.ActiveCell.Col).SetFocus() StationEditStatusMonitor.StationEditStatus = StationEditStatusMonitor.StationEditStatusEnum.Changed Next _uploading = False UnLockGridAutoRedraw() End Sub ''' ''' 节点降级 ''' Public Sub NodeMoveRight(rows As Integer) Dim node As RowNode If rows < 1 Then Return If _grd.ActiveCell Is Nothing OrElse _grd.Tree.SelectedNode Is Nothing Then Return If _headNode Is Nothing Then Return Dim grdNode As FlexCell.Node Dim grdPreNode As FlexCell.Node LockGridAutoRedraw() _uploading = True For idx As Integer = 1 To rows node = _headNode.RowList(_grd.ActiveCell.Row - _drawStartRow + idx) If node Is Nothing Then Exit For If node.RowType = RowNode.RowTypeEnum.FixedModule Then Exit For If node.RowIndex = 0 Then Exit For grdNode = _grd.Tree.FindNode(node.RowListIndex) grdPreNode = grdNode.PrevNode node.MoveRight() grdNode.Remove() grdPreNode.Nodes.Add("", "") UpdateGrid(_grd, node.RowListIndex, node) AddGridTreeNode(_grd.Tree.FindNode(node.RowListIndex), node) _grd.Cell(node.RowListIndex, _grd.ActiveCell.Col).SetFocus() StationEditStatusMonitor.StationEditStatus = StationEditStatusMonitor.StationEditStatusEnum.Changed Next _uploading = False UnLockGridAutoRedraw() End Sub #End Region #Region "外部事件" Public Sub Grid_RowNodeTextChanged(sender As Object, e As RowNodeChangedEventArgs) Dim row As Integer = e.Node.RowListIndex Dim node As RowNode = e.Node _uploading = True With _grd Select Case e.ChangeType Case RowNodeChangedEventArgs.RowNodeChangeType.Action .Cell(row, ColNames.Action).Text = IIf(node.Action, "1", "0").ToString() Case RowNodeChangedEventArgs.RowNodeChangeType.RowType If node.RowType = RowNode.RowTypeEnum.FixedModule Then .Cell(row, ColNames.Label).FontSize = 10 .Cell(row, ColNames.Label).FontBold = True ElseIf node.RowType = RowNode.RowTypeEnum.Module Then .Cell(row, ColNames.Label).FontSize = 8 .Cell(row, ColNames.Label).FontBold = True ElseIf node.RowType = RowNode.RowTypeEnum.Flow Then .Cell(row, ColNames.Label).FontSize = 8 .Cell(row, ColNames.Label).FontBold = False End If NodeActionChanged(node) ' NodeAction_Change(_grd, node.RowType, row, node.Action) Case RowNodeChangedEventArgs.RowNodeChangeType.Label .Cell(row, ColNames.Label).Text = $"{node.Label}" Case RowNodeChangedEventArgs.RowNodeChangeType.ControlType .Cell(row, ColNames.ControlType).Text = $"{node.ControlType}" Case RowNodeChangedEventArgs.RowNodeChangeType.Description .Cell(row, ColNames.Description).Text = $"{node.Description}" Case RowNodeChangedEventArgs.RowNodeChangeType.SaveToDb .Cell(row, ColNames.SaveToDb).Text = IIf(node.SaveToDb, "1", "0").ToString() Case RowNodeChangedEventArgs.RowNodeChangeType.RecordName .Cell(row, ColNames.RecordName).Text = $"{node.RecordName}" Case RowNodeChangedEventArgs.RowNodeChangeType.Retry .Cell(row, ColNames.Retry).Text = $"{node.Retry}" Case RowNodeChangedEventArgs.RowNodeChangeType.RetryInterval .Cell(row, ColNames.RetryInterval).Text = $"{node.RetryInterval}" Case RowNodeChangedEventArgs.RowNodeChangeType.ErrorCode .Cell(row, ColNames.ErrorCode).Text = $"{node.ErrorCode}" If String.IsNullOrWhiteSpace(node.ErrorCode) = False Then .Cell(row, ColNames.ErrorCode).BackColor = _errCodeManager(node.ErrorCode).Color .Cell(row, ColNames.ErrorMessage).BackColor = .Cell(row, ColNames.ErrorCode).BackColor Else .Cell(row, ColNames.ErrorCode).BackColor = Color.White .Cell(row, ColNames.ErrorMessage).BackColor = Color.White End If Case RowNodeChangedEventArgs.RowNodeChangeType.ErrorMessage .Cell(row, ColNames.ErrorMessage).Text = $"{node.ErrorMessage}" Case RowNodeChangedEventArgs.RowNodeChangeType.CommandType If String.Compare(.Cell(row, ColNames.CommandType).Text, node.CommandType) <> 0 Then .Cell(row, ColNames.CommandType).Text = $"{node.CommandType}" CommandTypeChanged(node) End If Case RowNodeChangedEventArgs.RowNodeChangeType.Command If String.Compare(.Cell(row, ColNames.Command).Text, node.Command) <> 0 Then .Cell(row, ColNames.Command).Text = $"{node.Command}" CommandChanged(node) End If Case RowNodeChangedEventArgs.RowNodeChangeType.Parameters .Cell(row, ColNames.Parameters).Text = $"{ParamsToString(node.Parameters)}" End Select End With StationEditStatusMonitor.StationEditStatus = StationEditStatusMonitor.StationEditStatusEnum.Changed _uploading = False End Sub Public Function CheckRecordDuplicateName() As Boolean Dim recodeNames As New Dictionary(Of String, Integer) For Each node As RowNode In _headNode.RowList If node.SaveToDb Then If String.IsNullOrWhiteSpace(node.RecordName) Then If MsgBox($"Record Name 无效!" & vbNewLine & "行号: " & node.RowListIndex & vbNewLine & "RecordName: [" & node.RecordName & "]" & vbNewLine & "是否继续操作?", MsgBoxStyle.OkCancel) = MsgBoxResult.Cancel Then Return False Else If recodeNames.ContainsKey(node.RecordName) Then If MsgBox("Record Name 重名!" & vbNewLine & "当前行号: " & node.RowListIndex & vbNewLine & "冲突行号: " & recodeNames(node.RecordName) & vbNewLine & "RecordName: " & node.RecordName & vbNewLine & vbNewLine & "请注意,记录名不能重复,否则前面的数据将会被覆盖!是否继续操作?", MsgBoxStyle.OkCancel ) = MsgBoxResult.Cancel Then Return False Else recodeNames.Add(node.RecordName, node.RowListIndex) End If End If End If Next Return True End Function Private Sub CheckRecordName_Duplicate(grd As Grid) Dim idx As Integer Dim x As Integer Dim tmpRecordName As String '更新信息数组中 UpdateGridInfo(grd) For idx = 0 To _grd.Rows - 2 If gRowNodeInfo(idx).NodeType = RowNode.RowTypeEnum.Flow Then tmpRecordName = gRowNodeInfo(idx).RecordName If tmpRecordName <> "" Then For x = idx + 1 To grd.Rows - 1 If tmpRecordName = gRowNodeInfo(x).RecordName Then MsgBox("Record Name 重名!" & vbNewLine & "行号: " & idx & vbNewLine & "行号: " & x & vbNewLine & "RecordName: " & tmpRecordName & vbNewLine & vbNewLine & "请注意,记录名不能重复,否则前面的数据将会被覆盖!" ) End If Next x End If End If Next idx End Sub ''' ''' 反显节点所在行 ''' ''' Public Sub TestNodeChanged(node As RowNode) _grd.Cell(node.RowListIndex, ColNames.Action).EnsureVisible() _grd.Cell(node.RowListIndex, ColNames.Action).BackColor = Color.Blue _grd.Range(node.RowListIndex, 1, node.RowListIndex, _grd.Cols - 1).SelectCells() End Sub Public Sub NodeCompleted(node As RowNode, testReturn As TestCommandReturn) Dim row As Integer = node.RowListIndex _grd.Cell(row, ColNames.Action).BackColor = CType(IIf(testReturn.ExecuteResult, Color.Green, Color.Red), Color) _grd.Cell(row, ColNames.Result).Text = testReturn.RecordValue _grd.Cell(row, ColNames.LowerLimit).Text = testReturn.LowerLimit _grd.Cell(row, ColNames.UpperLimit).Text = testReturn.UpperLimit _grd.Cell(row, ColNames.TimeElapsed).Text = testReturn.StepTimeSpan.TotalMilliseconds.ToString("N0") End Sub Public Sub ClearDebug() For i As Integer = 1 To _grd.Rows - 1 _grd.Cell(i, ColNames.Action).BackColor = Color.White _grd.Cell(i, ColNames.LowerLimit).Text = "" _grd.Cell(i, ColNames.UpperLimit).Text = "" _grd.Cell(i, ColNames.TimeElapsed).Text = "" _grd.Cell(i, ColNames.Result).Text = "" Next End Sub #End Region Public Enum ColNames ''' ''' 步骤,固定 ''' [Step] ''' ''' 断点执行,固定列 ''' [Pause] ''' ''' 是否运行 ''' Action ''' ''' 调试结果 ''' Result ''' ''' 节点下限 ''' LowerLimit ''' ''' 节点上限 ''' UpperLimit ''' ''' 节点测试耗时 ''' TimeElapsed ''' ''' 模块名称 ''' [Label] ''' ''' 节点解析 ''' Description ''' ''' 节点控制执行类型 ''' ControlType ''' ''' 命令类型 ''' CommandType ''' ''' 命令关键字 ''' Command ''' ''' 执行命令参数 ''' Parameters ''' ''' 失败重试次数 ''' Retry ''' ''' 重试间隔 ''' RetryInterval ''' ''' 当前返回值是否记录入库 ''' SaveToDb ''' ''' 返回值变量名 ''' RecordName ''' ''' 错误代码 ''' ErrorCode ''' ''' 错误提示 ''' ErrorMessage Max End Enum End Class End Namespace