鼠标悬停折叠/展开字形时的自定义树视图绘制错误
我在绘制所有模式下覆盖树视图的节点绘制事件,如下面的代码。
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
这完全按照我想要的方式绘制树视图,但由于某种原因,当您将鼠标悬停在打开/关闭元素上时,节点似乎会被重绘,但在最后一次重绘的顶部,导致文本看起来粗体,并且任何图像周围都有轮廓。但是,只有在未选择该节点的情况下才会发生这种情况,如果选择了该节点,则一切正常。抱歉,新用户无法发布屏幕转储。
我不确定您是否可以挂钩鼠标悬停字形事件以使控制无效,甚至检测绘图事件上的发送者,但我现在没有想法了。
尝试:
- 在绘制节点之前清除绘制时的图形对象
- 设置背景矩形并像选择时一样绘制节点
I'm overiding the node draw event for a treeview in draw all mode such as the code below.
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
This draws the tree view exactly as I want it but for some reason wen you mouse over the open/close elements the node seems get redrawn but over the top of its last redraw causing the text to look bolded and an outline around any images. This only happens however if the node is not selected and if it is selected then everything is fine. Sorry new user can't post screen dump.
I'm not sure if you can hook into the mouseover glyph event to just invalidate the control of even detect the sender on the draw event but im out of idears now.
Tried:
- Clearing the graphics object on draw before drawing node
- Setting background rectangle and drawing the node just like when selected
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我只能猜测,因为您无法发布图像,并且您包含的代码不完整(ActioNode?AssertionNode?)。
我知道您提到清除背景,但您发布的代码没有清除节点区域。尝试将其更改为这样的内容,看看它是否有效:
为什么要忽略所有异常?
您还需要处理您的字体。
I can only really guess since you couldn't post an image, and the code you included isn't complete (ActioNode? AssertionNode?).
I know you mentioned clearing the background, but the code you posted wasn't clearing the node area. Try changing it to something like this, see if it works:
Why are you ignoring all exceptions?
You also need to dispose your fonts.