【问题标题】:add button to TreeNode将按钮添加到 TreeNode
【发布时间】:2021-03-02 14:23:35
【问题描述】:

美好的一天。 有一个自定义控件,为每个Node添加一个按钮

Imports System.Windows.Forms.VisualStyles

Public Class CustomTreeView
    Inherits TreeView

    Private buttonRect As New Rectangle(80, 2, 50, 26)
    Private ReadOnly stringFormat As StringFormat

    Public Sub New()
        SetStyle(ControlStyles.OptimizedDoubleBuffer, True)

        DrawMode = TreeViewDrawMode.OwnerDrawText
        ShowLines = False
        FullRowSelect = True
        ItemHeight = 30

        stringFormat = New StringFormat With {
            .Alignment = StringAlignment.Near,
            .LineAlignment = StringAlignment.Center
        }
    End Sub

    Protected Overrides Sub OnDrawNode(ByVal e As DrawTreeNodeEventArgs)
        e.Graphics.DrawString(e.Node.Text, Me.Font, New SolidBrush(Me.ForeColor), e.Bounds, stringFormat)
        ButtonRenderer.DrawButton(e.Graphics, New Rectangle(e.Node.Bounds.Location + New Size(buttonRect.Location), buttonRect.Size), "btn", Me.Font, True, If(e.Node.Tag IsNot Nothing, CType(e.Node.Tag, PushButtonState), PushButtonState.Normal))
    End Sub

    Protected Overrides Sub OnNodeMouseClick(ByVal e As TreeNodeMouseClickEventArgs)
        Select Case e.Node.Tag
            Case Nothing, Is <> PushButtonState.Pressed
                Return
        End Select
        e.Node.Tag = PushButtonState.Normal
        MessageBox.Show(e.Node.Text & " clicked")
        ' force redraw
        e.Node.Text = e.Node.Text
    End Sub

    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        Dim tnode As TreeNode = GetNodeAt(e.Location)
        If tnode Is Nothing Then
            Return
        End If

        Dim btnRectAbsolute As New Rectangle(tnode.Bounds.Location + New Size(buttonRect.Location), buttonRect.Size)
        If btnRectAbsolute.Contains(e.Location) Then
            tnode.Tag = PushButtonState.Pressed
            tnode.Text = tnode.Text
        End If
    End Sub
End Class

告诉我如何只在第一个(主要)点头时显示按钮? 以及,当您单击此按钮时,如何不显示消息,而是调用某个过程?

【问题讨论】:

    标签: vb.net winforms treenode


    【解决方案1】:

    没有内置的按钮树节点。但是您可以自己创建一个具有按钮的自定义树节点。此自定义树节点继承自 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
    

    它有一个Private ReadOnly buttonText As String 来存储按钮的文本。普通节点文本和按钮文本在ButtonTreeNode的构造函数中传递:

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

    DrawNode 方法将被称为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
    

    你可以写的形式

    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
    

    这会向 TreeView 添加一个普通文本节点和一个自定义按钮节点。它还处理自定义 TreeView 的NodeButtonClick

    【讨论】:

      猜你喜欢
      • 2017-04-09
      • 2017-08-15
      • 2018-06-13
      • 2013-03-07
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多