I am developed a webcontrol which uses a treeview that dynamically populates data. The asp page which displays the webcontrol contains the webcontrol inside an atlas update panel. Depending on the user input, the treeview is initialised with either single or multiple rootnodes. The rootnode is then populated dynamically . The leafnodes ( third level nodes) have selectnodechanged event and check enabled.
The SelectNodechanged event works fine for the webcontrol when there is a single root node for the treeview. However when multiple rootnodes are created in the treeview, clicking on the leafnodes leads to an error "Index was out of range. Must be non negative or less than the size of the collection". Apparently the selectnodechanged event is not being caught by the event handler when multiple root nodes are being created. I am thinking this is somehow related to the atlas update panel that i am using. Could anyone point out the cause of the error ?
THe code for the asp page is shown below
<div id="icdTreeControlWrapper">
<atlas:UpdatePanel runat="server" ID="uxICDTreeUpdatePanel" Mode="conditional">
<ContentTemplate>
<discc:ICDTreeControl id = "ICDTree1" runat = "server" TreeType = "Indication" TreeTitle = "Indication for Procedure" FormCode = "4821" IsDetailsPanelEnabled = "true" />
</ContentTemplate>
<Triggers>
<atlas:ControlEventTrigger ControlID="ICDTree1" EventName="ICDTreeSelectedNodeChanged" />
</Triggers>
</atlas:UpdatePanel>
</div>
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
The source code for the webcontrol is shown below
public
class ICDTreeControl : CompositeControl, INamingContainer
{
#region
protected Label OutputMsgLabel;
protected Button SaveBtn;
protected Button CancelBtn;
protected TreeView ICDTreeView; //ICDTree;
protected Discc.Domain.ICDTree.ICDTreeDomain icdtreedomain;
#endregion
#region EventHandlers
public event EventHandler ICDTreeSelectedNodeChanged;
protected virtual void OnICDTreeSelectedNodeChanged(EventArgs e)
{
if (this.ICDTreeSelectedNodeChanged != null)
{
this.ICDTreeSelectedNodeChanged(this, e);
}
}
#endregion
public ICDTreeControl()
{
}
protected override void CreateChildControls()
{
icdtreedomain =
new Discc.Domain.ICDTree.ICDTreeDomain();
Controls.Clear();
CreateControlHierarchy();
ClearChildViewState();
validate =
new Validate();
}
protected virtual void CreateControlHierarchy()
{
OutputMsgLabel =
new Label();
Controls.Add(OutputMsgLabel);
ICDTreeView = new TreeView();
ICDTreeView.PopulateNodesFromClient = true;
ICDTreeView.EnableClientScript = true;
ICDTreeView.TreeNodeCheckChanged += new TreeNodeEventHandler(this.ICDTreeView_TreeNodeCheckChanged);
ICDTreeView.TreeNodePopulate += new TreeNodeEventHandler(this.ICDTreeView_TreeNodePopulate);
ICDTreeView.SelectedNodeChanged += new EventHandler(this.ICDTreeView_OnSelectedNodeChanged);
ICDTreeView.Enabled = true;
ICDTreeView.Visible = true;
ICDTreeView.ShowExpandCollapse = true;
ICDTreeView.ShowCheckBoxes = TreeNodeTypes.Leaf;
if (hasMultipleRootNodes)
{
DataSet ResultSet = icdtreedomain.GetIndicationTypes(formcode, en);
DataTable ICDTable = ResultSet.Tables[0];
if (ICDTable.Rows.Count > 0)
{
// Iterate through and create a new rootnode for each row in the query results.
foreach (DataRow row in ResultSet.Tables[0].Rows)
{
TreeNode NewNode = new TreeNode();
NewNode.SelectAction = TreeNodeSelectAction.Expand;
NewNode.PopulateOnDemand = true;
ICDTreeView.Nodes.Add(NewNode);
}
}
}
else // Only one root node for the tree
{
TreeNode RootNode = new TreeNode();
RootNode.SelectAction = TreeNodeSelectAction.Expand;
RootNode.PopulateOnDemand = true;
ICDTreeView.Nodes.Add(RootNode);
RootNode.Expand();
}
SaveBtn =
new Button();
SaveBtn.Click += new EventHandler(this.OnClick_SaveBtn);
Controls.Add(SaveBtn);
Controls.Add(ICDTreeView);
}
protected override void Render(HtmlTextWriter writer)
{
OutputMsgLabel.RenderControl(writer);
SaveBtn.RenderControl(writer);
ICDTreeView.RenderControl(writer);
}
protected virtual void ICDTreeView_TreeNodePopulate(object sender, System.Web.UI.WebControls.TreeNodeEventArgs e)
{
switch (e.Node.Depth)
{
case 0:
PopulateCategories(e.Node);
break;
}
}
void PopulateCategories(TreeNode parent)
{
try
{
DataSet ResultSet = icdtreedomain.GetICDCategories();
DataTable ICDTable = ResultSet.Tables[0];
if (ICDTable.Rows.Count > 0)
{
// Iterate through and create a new node for each row in the query results.
foreach (DataRow row in ResultSet.Tables[0].Rows)
{
// Create the category nodes.
TreeNode NewNode = new TreeNode();
// Set additional properties for the node.
NewNode.SelectAction =
TreeNodeSelectAction.Expand;
// Add the ICD category to the ChildNodes collection of the root node.
parent.ChildNodes.Add(NewNode);
parent.PopulateOnDemand =
true;
PopulateSubcategory(NewNode);
}
}
}
catch (SqlException ex)
{
OutputMsgLabel.Text +=
"Error: " + ex.Errors.ToString() + "<br/>";
}
}
void PopulateSubcategory(TreeNode parent)
{
try
{
// Query for the icds of the current category. These are the values
// for the third-level nodes.
DataSet ResultSet = icdtreedomain.GetSubCategories
DataTable ICDTable = ResultSet.Tables[0];
if (ICDTable.Rows.Count > 0)
{
// Iterate through and create a new node for each row in the query results.
foreach (DataRow row in ResultSet.Tables[0].Rows)
{
// Create the new node.
TreeNode NewNode = new TreeNode();
NewNode.PopulateOnDemand = false;
// Set additional properties for the node.
NewNode.SelectAction = TreeNodeSelectAction.Select;
// Add the new node to the ChildNodes collection of the parent node.
parent.ChildNodes.Add(NewNode);
}
}
}
catch (SqlException ex)
{
OutputMsgLabel.Text +=
"Error: " + ex.Errors.ToString() + "<br/>";
}
}
// public event EventHandler SelectedNodeChanged;
protected virtual void ICDTreeView_OnSelectedNodeChanged(object sender, EventArgs e)
{
if (ICDTreeView.SelectedNode.Depth > 1)
{
if (ICDTreeView.SelectedNode.Checked == true)
{
GetSelectedNodeInfo();
}
this.OnICDTreeSelectedNodeChanged(e);
}
public void OnClick_SaveBtn(object sender, EventArgs e)
{
}
// The TreeNodeCheckChanged event is raised when a check box in the TreeView control changes state between posts to the server
// Even though the TreeNodeCheckChanged event is fired on post back, changing a check box does not cause a post back.
protected void ICDTreeView_TreeNodeCheckChanged(Object sender, TreeNodeEventArgs e)
{
try
{
DataSet ResultSet = icdtreedomain.GetCurrentSelections();
DataTable ICDTable = ResultSet.Tables[0];
if (ICDTable.Rows.Count > 0)
{
// Iterate through the root nodes in the Nodes property.
for (int i = 0; i < ICDTreeView.Nodes.Count; i++)
{
// Check if status has been changed for the nodes.
CheckNodeStatus();
}
}
}
catch (SqlException ex)
{
OutputMsgLabel.Text +=
"Error: " + ex.Errors.ToString() + "<br/>";
}
}
}