Vb.net 鼠标悬停折叠/展开图示符上的自定义treeview绘制错误

Vb.net 鼠标悬停折叠/展开图示符上的自定义treeview绘制错误,vb.net,treeview,mouseover,ondraw,glyph,Vb.net,Treeview,Mouseover,Ondraw,Glyph,我正在以draw all模式覆盖树视图的节点绘制事件,如下面的代码 Protected Overrides Sub OnDrawNode(ByVal e As System.Windows.Forms.DrawTreeNodeEventArgs) Try Dim Indent = e.Node.Level * Me.Indent + 32 Dim font = Me.Font 'draw selected If e.Sta

我正在以draw all模式覆盖树视图的节点绘制事件,如下面的代码

 Protected Overrides Sub OnDrawNode(ByVal e As System.Windows.Forms.DrawTreeNodeEventArgs)
    Try
        Dim Indent = e.Node.Level * Me.Indent + 32
        Dim font = Me.Font
        'draw selected
        If e.State And TreeNodeStates.Selected Then
            Dim rect As New Rectangle(0, e.Bounds.Location.Y, Me.Width - 1, e.Bounds.Height - 1)
            e.Graphics.FillRectangle(Brushes.AliceBlue, rect)
            e.Graphics.DrawRectangle(Pens.DarkSlateBlue, rect)
        End If


        'draw status icon
        e.Graphics.DrawImage(Me.ImageList.Images(e.Node.ImageIndex), New Point(e.Bounds.X + indent - Me.ImageList.ImageSize.Width + 2, e.Bounds.Y + ((Me.ItemHeight / 2) - (Me.ImageList.ImageSize.Height / 2))))

        'draw collapse glyph
        If e.Node.Nodes.Count > 0 Then
            Dim element As VisualStyleElement
            Dim glyphRect = New Rectangle(e.Bounds.Location.X + 2 + e.Node.Level * Me.Indent, e.Bounds.Location.Y + 8, 16, 16)
            If e.Node.IsExpanded Then
                element = VisualStyleElement.TreeView.Glyph.Opened
            Else
                element = VisualStyleElement.TreeView.Glyph.Closed
            End If

            Dim renderer As New VisualStyleRenderer(element)
            renderer.DrawBackground(e.Graphics, glyphRect)
        End If

        If e.Node.Level.Equals(0) Then
            font = New Font(Me.Font.Name, 12, FontStyle.Regular)
            e.Graphics.DrawString(e.Node.Text, font, Brushes.MidnightBlue, New Point(indent + 5, e.Bounds.Location.Y + 5), New StringFormat())
        ElseIf e.Node.Level.Equals(1) Then
            'action
            Dim params = CType(e.Node, ActionNode).Params

            Dim x = indent + 5
            e.Graphics.DrawString(e.Node.Text, Me.Font, Brushes.Black, New Point(x, e.Bounds.Location.Y + 2), New StringFormat())
            For Each param In params
                e.Graphics.DrawString(param.Key & ":", Me.Font, Brushes.DarkSlateBlue, New Point(x, e.Node.Bounds.Location.Y + 15))
                x += e.Graphics.MeasureString(param.Key & ":", Me.Font).Width - 1
                e.Graphics.DrawString(param.Value, Me.Font, Brushes.SlateGray, New Point(x, e.Node.Bounds.Location.Y + 15))
                x += e.Graphics.MeasureString(param.Value, Me.Font).Width
            Next

        ElseIf e.Node.Level.Equals(2) Then
            'assertion
            Dim params = CType(e.Node, AssertionNode).Params

            Dim x = indent + 5
            e.Graphics.DrawString(e.Node.Text, Me.Font, Brushes.Black, New Point(x, e.Bounds.Location.Y + 2), New StringFormat())
            For Each param In params
                e.Graphics.DrawString(param.Key & ":", Me.Font, Brushes.DarkSlateBlue, New Point(x, e.Node.Bounds.Location.Y + 15))
                x += e.Graphics.MeasureString(param.Key & ":", Me.Font).Width - 1
                e.Graphics.DrawString(param.Value, Me.Font, Brushes.SlateGray, New Point(x, e.Node.Bounds.Location.Y + 15))
                x += e.Graphics.MeasureString(param.Value, Me.Font).Width
            Next
        End If
    Catch ex As Exception

    End Try
End Sub
这会完全按照我的要求绘制树视图,但由于某些原因,如果将鼠标悬停在打开/关闭元素上,节点似乎会被重新绘制,但会超出其上次重新绘制的顶部,从而导致文本看起来粗体,并在任何图像周围显示轮廓。但是,只有在未选择节点时才会发生这种情况,如果选择了节点,则一切正常。抱歉,新用户无法发布屏幕转储

我不确定你是否可以钩住鼠标悬停标志符号事件,使draw事件中的控制失效,甚至检测发送者,但我现在不太理想

尝试:

  • 在绘图节点之前清除绘图上的图形对象
  • 设置背景矩形并像选中时一样绘制节点

我只能猜测,因为您无法发布图像,并且您包含的代码不完整(ActioNode?AssertionNode?)

我知道你提到了清除背景,但是你发布的代码没有清除节点区域。尝试将其更改为类似以下内容,看看是否有效:

Dim rect As New Rectangle(0, e.Bounds.Top, Me.ClientSize.Width - 1, e.Bounds.Height - 1)
If e.State And TreeNodeStates.Selected Then
  e.Graphics.FillRectangle(Brushes.AliceBlue, rect)
  e.Graphics.DrawRectangle(Pens.DarkSlateBlue, rect)
Else
  e.Graphics.FillRectangle(SystemBrushes.Window, rect)
End If
你为什么忽视所有的例外


您还需要处理字体。

我只能猜测,因为您无法发布图像,并且您包含的代码不完整(ActioNode?AssertionNode?)

我知道你提到了清除背景,但是你发布的代码没有清除节点区域。尝试将其更改为类似以下内容,看看是否有效:

Dim rect As New Rectangle(0, e.Bounds.Top, Me.ClientSize.Width - 1, e.Bounds.Height - 1)
If e.State And TreeNodeStates.Selected Then
  e.Graphics.FillRectangle(Brushes.AliceBlue, rect)
  e.Graphics.DrawRectangle(Pens.DarkSlateBlue, rect)
Else
  e.Graphics.FillRectangle(SystemBrushes.Window, rect)
End If
你为什么忽视所有的例外


您还需要处理字体。

您必须绘制背景,填充整个电子边界您必须绘制背景,填充整个e.BoundsHello是的,我清除了图形对象,因为它似乎没有任何效果。我不知道为什么我不认为这是唯一一点不同的代码为一个选定的节点,似乎工作正常。我并没有忽略所有的异常,我只是把它放进去看看是否抛出了异常,或者抛出了什么异常,以获得更多的细节。我只是在使用真实的treeview字体,我不知道我需要处理它,但现在我会感谢你。最后,对于操作/断言节点的混乱表示抱歉。它们只是继承treenode的类,用于在绘制节点时添加一些所需的数据。您好,是的,我清除了图形对象,因为它似乎没有任何效果。我不知道为什么我不认为这是所选节点唯一不同的代码,它似乎工作正常。我并没有忽略所有的异常,我只是把它放进去看看是否抛出了异常,或者抛出了什么异常,以获得更多的细节。我只是在使用真实的treeview字体,我不知道我需要处理它,但现在我会感谢你。最后,对于操作/断言节点的混乱表示抱歉。它们只是继承treenode的类,用于在绘制节点时添加所需的数据。