2014年7月13日 星期日

[RESOLVED] Unable to cast object of type 'System.EventArgs' to type 'System.Web.UI.WebControls.TreeNode EventArgs


I have a treeview dynamically populated from database based on the value in the dropdown. I am trying to achieve this by firing the populatenode on selected event changed event. However "Unable to cast object of type 'System.EventArgs' to type 'System.Web.UI.WebControls.TreeNode
EventArgs". All I am trying to do is to obtain the courseID from dropdown.Selectedvalue, convert it into an integer and display only the nodes associated with that particular value. Please help!


Here's my code:


Aspx page code




DataSourceID="SqlDataSource1" DataTextField="Coursename"
DataValueField="Coursename" style="width: 77px"
OnSelectedIndexChanged="PopulateNode" AutoPostBack="True" AppendDataBoundItems="true" >
Please select a course

ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [Coursename], [CourseID] FROM [courseinfo]">


Font-Names= "Arial"
ForeColor="Blue"
EnableClientScript="true"
PopulateNodesFromClient="true"
OnTreeNodePopulate="PopulateNode"
runat="server">



SelectAction="Expand"
PopulateOnDemand="true"/>













VB Code


Sub PopulateNode(ByVal sender As Object, ByVal e As TreeNodeEventArgs)

' Call the appropriate method to populate a node at a particular level.
Select Case e.Node.Depth

Case 0
' Populate the first-level nodes.
PopulateChapters(e.Node)

Case 1
' Populate the second-level nodes.
PopulateTopics(e.Node)

Case Else
' Do nothing.

End Select

End Sub

Sub PopulateChapters(ByVal node As TreeNode)

' Query for the product categories. These are the values
' for the second-level nodes.

If (DropDownList1.SelectedIndex > 0) Then
Dim curcourse As Integer = Convert.ToInt32(DropDownList1.SelectedValue)
Dim command As New SqlCommand("Select ChapterID, ChapterName, CourseID, ChapterContent From coursechapters Where CourseID=@CourseID")
command.Parameters.AddWithValue("CourseID", curcourse)
Dim ResultSet As DataSet = Nothing
Dim da As New SqlDataAdapter(command)
da.Fill(ResultSet)
' Create the second-level nodes.
If ResultSet.Tables.Count > 0 Then

' Iterate through and create a new node for each row in the query results.
' Notice that the query results are stored in the table of the DataSet.
Dim row As DataRow

For Each row In ResultSet.Tables(0).Rows

' Create the new node. Notice that the CategoryId is stored in the Value property
' of the node. This will make querying for items in a specific category easier when
' the third-level nodes are created.
Dim newNode As TreeNode = New TreeNode()
newNode.Text = row("ChapterName").ToString()
newNode.Value = row("ChapterID").ToString()
' Set the PopulateOnDemand property to true so that the child nodes can be
' dynamically populated.
newNode.PopulateOnDemand = True

' Set additional properties for the node.
newNode.SelectAction = TreeNodeSelectAction.SelectExpand

' Add the new node to the ChildNodes collection of the parent node.
node.ChildNodes.Add(newNode)

Next

End If
End If


End Sub

Sub PopulateTopics(ByVal node As TreeNode)

' Query for the products of the current category. These are the values
' for the third-level nodes.
If (DropDownList1.SelectedIndex > 0) Then
Dim curcourse As Integer = Convert.ToInt32(DropDownList1.SelectedValue)
Dim chapterIDvalue As Integer = node.Value
Dim conn As New SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\myelms.mdf;Integrated Security=True;User Instance=True; MultipleActiveResultSets=True")
Dim Command As New SqlCommand("Select TopicID,TopicName,CourseID,ChapterID,TopicContent From CourseContent Where ChapterID=@ChapterID And CourseID=@courseID", conn)
Command.Parameters.AddWithValue("@ChapterID", chapterIDvalue)
Command.Parameters.AddWithValue("CourseID", curcourse)
Dim ResultSet As DataSet = Nothing
Dim da As New SqlDataAdapter(Command)
da.Fill(ResultSet)
' Create the third-level nodes.
If ResultSet.Tables.Count > 0 Then

' Iterate through and create a new node for each row in the query results.
' Notice that the query results are stored in the table of the DataSet.
Dim row As DataRow

For Each row In ResultSet.Tables(0).Rows

' Create the new node.
Dim NewNode As TreeNode = New TreeNode(row("TopicName").ToString())

' Set the PopulateOnDemand property to false, because these are leaf nodes and
' do not need to be populated.
NewNode.PopulateOnDemand = False

' Set additional properties for the node.
NewNode.SelectAction = TreeNodeSelectAction.SelectExpand

' Add the new node to the ChildNodes collection of the parent node.
node.ChildNodes.Add(NewNode)

Next

End If
End If
End Sub

Thank you in advance,


Sai.



If that is not possible, can you please suggest another way to do this?


Thanks again.


Sai.



The error message is a good indicator here. You have the SelectedIndexChanged event of your dropdownlist pointing to PopulateNode. Look at the second parameter of your event handler.


Sub PopulateNode(ByVal sender As Object, ByVal e As TreeNodeEventArgs)

This is a dropdown list's event handler not a treeview's event handle. The second parameter isn't a TreeNodeEventArgs which is the wrong type for of event argument paremeter for a dropdown lists's event. Replace it with the System.EventArgs mentioned in
the error. 





markfitzme


This is a dropdown list's event handler not a treeview's event handle. The second parameter isn't a TreeNodeEventArgs which is the wrong type for of event argument paremeter for a dropdown lists's event. Replace it with the System.EventArgs mentioned in the
error. 


Thank you for your reply. I have understood that part. However if I change it to System.EventArgs, it would throw an error, node(as in e.node) is not a member of System.EventArgs. Is there a way for me to pass the dropdownlist.selected value(as a parameter)
into the populate chapters and populate topics functions so that I do not have to use the selected index changed event of the dropdown?


Thanks again,


Sai.



You just can't have both point to the same function, it isn't possible because the event handlers are completely different. The event handler for the dropdown list would never have a node property anyways because it is a dropdown list.


You could use the SelectedNode property of the tree to get the currently selected tree node. http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.treeview.selectednode(v=vs.110).aspx




Ok. Thanks. I just needed the confirmation. In that case can I attempt something like this? Without using the selectedIndexChanged ofcourse


Sub PopulateNode(ByVal sender As Object, ByVal e As TreeNodeEventArgs)

If (DropDownList1.SelectedIndex > 0) Then
Try
Dim curcourseID As Integer = Convert.ToInt32(DropDownList1.SelectedValue)
' Call the appropriate method to populate a node at a particular level.
Select Case e.Node.Depth

Case 0
' Populate the first-level nodes.
PopulateChapters((e.Node), curcourseID)

Case 1
' Populate the second-level nodes.
PopulateTopics(e.Node)

Case Else
' Do nothing.

End Select
Catch ex As Exception
errmsg.Text = ex.Message
End Try
Else
errmsg.Text = "Please select a course from the dropdownlist"
End If


End Sub

Sub PopulateChapters(ByVal node As TreeNode, ByVal curcourse As Integer)

' Query for the product categories. These are the values
' for the second-level nodes.

If (DropDownList1.SelectedIndex > 0) Then
curcourse = Convert.ToInt32(DropDownList1.SelectedValue)
Dim command As New SqlCommand("Select ChapterID, ChapterName, CourseID, ChapterContent From coursechapters Where CourseID=@CourseID")
command.Parameters.AddWithValue("CourseID", curcourse)
Dim ResultSet As DataSet = Nothing
Dim da As New SqlDataAdapter(command)
da.Fill(ResultSet)
' Create the second-level nodes.
If ResultSet.Tables.Count > 0 Then

' Iterate through and create a new node for each row in the query results.
' Notice that the query results are stored in the table of the DataSet.
Dim row As DataRow

For Each row In ResultSet.Tables(0).Rows

' Create the new node. Notice that the CategoryId is stored in the Value property
' of the node. This will make querying for items in a specific category easier when
' the third-level nodes are created.
Dim newNode As TreeNode = New TreeNode()
newNode.Text = row("ChapterName").ToString()
newNode.Value = row("ChapterID").ToString()
' Set the PopulateOnDemand property to true so that the child nodes can be
' dynamically populated.
newNode.PopulateOnDemand = True

' Set additional properties for the node.
newNode.SelectAction = TreeNodeSelectAction.SelectExpand

' Add the new node to the ChildNodes collection of the parent node.
node.ChildNodes.Add(newNode)

Next

End If
End If
End Sub



Hi,


If you did not use selectedIndexChanged function, I do not know when you will call
PopulateNode function. There is a smilar thread, please refer to the link below:


http://forums.asp.net/t/1988483.aspx?How+do+I+populate+a+treeview+depending+on+the+value+selected+in+the+dropdown


I searched somethings about selectedIndexChanged, we can call BindParentTreeNode function, please refer to the link below:


http://www.dotnetspider.com/forum/255382-Populate-treeview-nodes-by-selecting-dropdownlist.aspx


Hope it's useful for you.


Best Regards,


Michelle Ge



Actually I was the one who posted that thread. It results in a null reference exception. It is understandable because we are not passing any nodes. Any way I have figured out an alternate solution. Thank you for your help.







沒有留言:

張貼留言