我可以将带事件的按钮添加到自定义treeNode吗?

时间:2009-12-22 16:41:16

标签: asp.net vb.net custom-controls

我扩展了treeview,treenode和nodetype,因此我可以拥有自定义节点。某些节点上有图像按钮,允许它们添加子节点或删除节点。我无法处理按钮中的任何事件。

Public Class ContentTreeView
Inherits TreeView

Public Event OnAddChild(ByVal sender As Object, ByVal e As EventArgs)
Public Event OnDelete(ByVal sender As Object, ByVal e As EventArgs)

Private _AddImageURL As String = String.Empty
Private _DeleteImageURL As String = String.Empty

Public Property AddImageURL() As String
    Get
        Return _AddImageURL
    End Get
    Set(ByVal value As String)
        _AddImageURL = value
    End Set
End Property

Public Property DeleteImageURL() As String
    Get
        Return _DeleteImageURL
    End Get
    Set(ByVal value As String)
        _DeleteImageURL = value
    End Set
End Property

Protected Overrides Function CreateNode() As TreeNode
    Dim retval As ContentTreeNode = New ContentTreeNode(AddImageURL, DeleteImageURL)
    AddHandler retval.OnAddChild, AddressOf ContentNode_AddChild
    AddHandler retval.OnDelete, AddressOf ContentNode_Delete
    Return retval
End Function

Protected Sub ContentNode_AddChild(ByVal sender As Object, ByVal e As EventArgs)
    RaiseEvent OnAddChild(Nothing, Nothing)
End Sub
Protected Sub ContentNode_Delete(ByVal sender As Object, ByVal e As EventArgs)
    RaiseEvent OnDelete(Nothing, Nothing)
End Sub

Public Class ContentTreeNode
    Inherits TreeNode

    Public Event OnAddChild(ByVal sender As Object, ByVal e As EventArgs)
    Public Event OnDelete(ByVal sender As Object, ByVal e As EventArgs)

    Private _AddImageURL As String = String.Empty
    Private _DeleteImageURL As String = String.Empty

    Private btnAddChild As ImageButton
    Private btnDelete As ImageButton

    Public Sub New(ByVal AddImageURL_ As String, ByVal DeleteImageURL_ As String)
        _AddImageURL = AddImageURL_
        _DeleteImageURL = DeleteImageURL_
    End Sub

    Public Property AddImageURL() As String
        Get
            Return _AddImageURL
        End Get
        Set(ByVal value As String)
            _AddImageURL = value
        End Set
    End Property

    Public Property DeleteImageURL() As String
        Get
            Return _DeleteImageURL
        End Get
        Set(ByVal value As String)
            _DeleteImageURL = value
        End Set
    End Property

    Protected Overrides Sub RenderPreText(ByVal writer As HtmlTextWriter)
    End Sub

    Protected Overrides Sub RenderPostText(ByVal writer As HtmlTextWriter)
        CreateChildControls()
        If GetTreeNodeType() <> ContentTreeNodeTypes.Root Then
            btnAddChild.RenderControl(writer)
            If GetTreeNodeType() <> ContentTreeNodeTypes.Category Then
                btnDelete.RenderControl(writer)
            End If
        End If
    End Sub

    Private Function GetTreeNodeType() As TreeNodeTypes
        Dim leaf As TreeNodeTypes = TreeNodeTypes.Leaf
        If ((Me.Depth = 0) AndAlso (Me.ChildNodes.Count > 0)) Then
            Return ContentTreeNodeTypes.Root
        End If
        If Me.Depth = 1 Then
            Return ContentTreeNodeTypes.Category
        End If
        If ((Me.ChildNodes.Count <= 0) AndAlso Not Me.PopulateOnDemand) Then
            Return leaf
        End If
        Return ContentTreeNodeTypes.Parent
    End Function

    Protected Sub CreateChildControls()
        'Controls.Clear()

        '***Creat Add Button***
        btnAddChild = New ImageButton()
        btnAddChild.ID = "btnAddChild"
        btnAddChild.ImageUrl = AddImageURL
        btnAddChild.ToolTip = "Add Child"
        AddHandler btnAddChild.Click, AddressOf btnAddChild_Click

        '***Create DeleteButton***
        btnDelete = New ImageButton()
        btnDelete.ID = "btnDelete"
        btnDelete.ImageUrl = DeleteImageURL()
        btnDelete.ToolTip = "Delete Page"
        AddHandler btnDelete.Click, AddressOf btnDelete_Click

        ''***Add Controls***
        'Me.Controls.Add(btnAddChild)
        'Me.Controls.Add(btnDelete)
    End Sub

    Protected Sub btnAddChild_Click(ByVal sender As Object, ByVal e As EventArgs)
        RaiseEvent OnAddChild(Nothing, Nothing)
    End Sub
    Protected Sub btnDelete_Click(ByVal sender As Object, ByVal e As EventArgs)
        RaiseEvent OnDelete(Nothing, Nothing)
    End Sub


    Public Enum ContentTreeNodeTypes
        All = 7
        Leaf = 4
        None = 0
        Parent = 2
        Root = 1
        Category = 3
    End Enum
End Class

结束班

1)我可以实现像IPostBackEventHandler这样的东西吗? 2)这是否可行,因为treeNode不是控件/ web控件?

感谢任何帮助......谢谢!

2 个答案:

答案 0 :(得分:0)

我认为这个问题与时间有关,这意味着在ASP.Net page lifecycle后期将子控件添加到要执行的事件中。

这可能会解决问题:

  1. 尽早构建整个树结构,例如:在页面的Init事件中。
  2. 将子ImageButton附加到ContentTreeNode的构造函数中。
  3. 或者您可以使用javascript上下文菜单,这样您就不需要将任何子控件附加到TreeNode ...

答案 1 :(得分:0)

阅读此post后。我决定使用以下解决方案。首先,我将CreateChildControls方法更改为:

        Protected Sub CreateChildControls()
        Dim page As Page = HttpContext.Current.CurrentHandler
        Dim csm As ClientScriptManager = page.ClientScript
        Dim control As WebControl = page.Master.FindControl(_ContainerID).FindControl(_ContentTreeViewID)

        '***Creat Add Button***
        btnAddChild = New ImageButton()
        btnAddChild.ID = "btnAddChild"
        btnAddChild.ImageUrl = AddImageURL
        btnAddChild.ToolTip = "Add Child"            
        btnAddChild.Attributes.Add("onClick", csm.GetPostBackEventReference(control, String.Format("{0}:{1}", Me.Value, "Add")))

        '***Create DeleteButton***
        btnDelete = New ImageButton()
        btnDelete.ID = "btnDelete"
        btnDelete.ImageUrl = DeleteImageURL()
        btnDelete.ToolTip = "Delete Page"
        btnDelete.Attributes.Add("onClick", csm.GetPostBackEventReference(control, String.Format("{0}:{1}", Me.Value, "Delete")))
    End Sub

然后我必须在自定义树视图中实现IPostBackEventHandler来处理回发事件。也许不是最好的解决方案,但它适用于自定义事件args。