Vb.net 向TreeNode添加按钮

Vb.net 向TreeNode添加按钮,vb.net,winforms,treenode,Vb.net,Winforms,Treenode,你好。 有一个自定义控件,它向每个节点添加一个按钮 导入System.Windows.Forms.VisualStyles 公共类CustomTreeView 继承TreeView 私有按钮删除为新矩形(80,2,50,26) 私有只读stringFormat作为stringFormat 公共分新() SetStyle(ControlStyles.OptimizedDoubleBuffer,True) DrawMode=TreeViewDrawMode.OwnerDrawText ShowLin

你好。 有一个自定义控件,它向每个节点添加一个按钮

导入System.Windows.Forms.VisualStyles
公共类CustomTreeView
继承TreeView
私有按钮删除为新矩形(80,2,50,26)
私有只读stringFormat作为stringFormat
公共分新()
SetStyle(ControlStyles.OptimizedDoubleBuffer,True)
DrawMode=TreeViewDrawMode.OwnerDrawText
ShowLines=False
FullRowSelect=True
项目高度=30
stringFormat=带有{
.Alignment=StringAlignment.Near,
.LineAlignment=StringAlignment.Center
}
端接头
受保护的覆盖子OnDrawNode(由值e作为DrawTreeNodeEventArgs)
e、 Graphics.DrawString(e.Node.Text、Me.Font、新SolidBrush(Me.ForeColor)、e.Bounds、stringFormat)
ButtonRenderer.DrawButton(例如图形、新矩形(例如Node.Bounds.Location+新大小(buttonRect.Location)、buttonRect.Size)、“btn”、Me.Font、True、If(例如e.Node.Tag不是空的、CType(例如Node.Tag、PushButtonState)、PushButtonState.Normal))
端接头
节点DemouseClick上的受保护覆盖子节点(通过值e作为TreeNodeMouseClickEventArgs)
选择Case e.Node.Tag
无案例,按按钮状态。按下
返回
结束选择
e、 Node.Tag=PushButtonState.Normal
MessageBox.Show(e.Node.Text&“单击”)
“强制重画
e、 Node.Text=e.Node.Text
端接头
MouseDown上的受保护覆盖子对象(以鼠标指针形式显示)
尺寸tnode为TreeNode=GetNode(如位置)
如果tnode什么都不是,那么
返回
如果结束
将btnRectAbsolute尺寸调整为新矩形(tnode.Bounds.Location+新尺寸(buttonRect.Location),buttonRect.Size)
如果btnRecatabsolute.Contains(e.Location)则
tnode.Tag=按钮状态。按下
tnode.Text=tnode.Text
如果结束
端接头
末级
告诉我如何仅在第一次(主要)点头时显示按钮?
当您单击此按钮时,如何不显示消息,而是调用某个过程?

没有内置的按钮树节点。但是,您可以自己创建一个自定义树节点,其中包含一个按钮。此自定义树节点继承自
TreeNode
。为了提高可扩展性,我们为具有
DrawNode
方法的树节点声明了一个接口:

Imports System.Windows.Forms.VisualStyles

Public Interface ICustomDrawTreeNode
    Sub DrawNode(ByVal e As DrawTreeNodeEventArgs, buttonState As PushButtonState)
End Interface
我们还创建了一个模块,其中包含自定义树视图和自定义树节点中使用的一些设置

Module Settings
    Public ReadOnly ButtonRect As New Rectangle(80, 2, 50, 26)

    Public ReadOnly TextStringFormat = New StringFormat() With {
        .Alignment = StringAlignment.Near,
        .LineAlignment = StringAlignment.Center,
        .FormatFlags = StringFormatFlags.NoClip Or StringFormatFlags.FitBlackBox Or StringFormatFlags.LineLimit
    }

End Module
然后我们可以实现这样一个按钮节点

Imports System.Windows.Forms.VisualStyles

Public Class ButtonTreeNode
    Inherits TreeNode
    Implements ICustomDrawTreeNode

    Private ReadOnly buttonText As String

    Public Sub New(text As String, buttonText As String)
        MyBase.New(text)

        Me.buttonText = buttonText
    End Sub

    Public Sub DrawNode(e As DrawTreeNodeEventArgs, buttonState As PushButtonState) _
        Implements ICustomDrawTreeNode.DrawNode

        Dim font As Font = e.Node.TreeView.Font

        ' Draw Text to the left of the button
        Dim rect As Rectangle = New Rectangle(
            e.Node.Bounds.Location,
            New Size(Settings.ButtonRect.Left, e.Bounds.Height))
        e.Graphics.DrawString(e.Node.Text, font, Brushes.Black, rect, Settings.TextStringFormat)

        ' Draw the button
        rect = New Rectangle(
            e.Node.Bounds.Location + Settings.ButtonRect.Location,
            Settings.ButtonRect.Size)
        ButtonRenderer.DrawButton(e.Graphics, rect, buttonText, font, True, buttonState)
    End Sub
End Class
它有一个
专用只读按钮文本作为字符串
,用于存储按钮的文本。将普通节点文本和按钮文本传递到
buttontreNode
的构造函数中:

Public Sub New(text As String, buttonText As String)
OnDrawNode
中的
CustomTreeView
方法将被调用


CustomTreeView
中,我声明了一个
NodeButtonClick
事件,该事件将在单击节点的按钮时引发。然后可以在表单中处理此事件。在设计器中选择
CustomTreeView
时,此新事件将出现在事件的“操作”部分

Imports System.ComponentModel
Imports System.Windows.Forms.VisualStyles

Public Class CustomTreeView
    Inherits TreeView

    <Category("Action")>
    Public Event NodeButtonClick(e As TreeNodeMouseClickEventArgs)

    Private _isButtonPressed As Boolean

    Public Sub New()
        SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
        DrawMode = TreeViewDrawMode.OwnerDrawText
        ShowLines = False
        FullRowSelect = True
        ItemHeight = 30
    End Sub

    Protected Overrides Sub OnDrawNode(e As DrawTreeNodeEventArgs)
        Dim customDrawNode As ICustomDrawTreeNode = TryCast(e.Node, ICustomDrawTreeNode)
        If customDrawNode Is Nothing Then ' Normal text node.
            e.Graphics.DrawString(e.Node.Text, Font, Brushes.Black, e.Node.Bounds, Settings.TextStringFormat)
        Else
            customDrawNode.DrawNode(e, If(_isButtonPressed, PushButtonState.Pressed, PushButtonState.Normal))
        End If
    End Sub

    Protected Overrides Sub OnNodeMouseClick(e As TreeNodeMouseClickEventArgs)
        If _isButtonPressed Then
            _isButtonPressed = False
            Refresh()
            Dim buttonNode = TryCast(e.Node, ButtonTreeNode)
            If buttonNode IsNot Nothing Then
                RaiseEvent NodeButtonClick(e)
            End If
        End If
    End Sub

    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        Dim buttonNode = TryCast(GetNodeAt(e.Location), ButtonTreeNode)
        If buttonNode IsNot Nothing Then
            Dim btnRectAbsolute As New Rectangle(
                buttonNode.Bounds.Location + Settings.ButtonRect.Location,
                Settings.ButtonRect.Size)
            _isButtonPressed = btnRectAbsolute.Contains(e.Location)
            If _isButtonPressed Then
                Refresh()
            End If
        End If
    End Sub
End Class
这将向树视图添加一个普通文本节点和一个自定义按钮节点。它还处理自定义树视图的
NodeButtonClick

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        TreeView1.Nodes.Add("Text")
        TreeView1.Nodes.Add(New ButtonTreeNode("Caption", "Button"))
    End Sub

    Private Sub TreeView1_NodeButtonClick(e As TreeNodeMouseClickEventArgs) _
        Handles TreeView1.NodeButtonClick

        MessageBox.Show(e.Node.Text & " clicked")
    End Sub
End Class