void RenderNode (HtmlTextWriter writer, TreeNode node, int level, ArrayList levelLines, bool hasPrevious, bool hasNext)
{
// FIXME: disabled for now - needs closer investigation
//if (node.PopulateOnDemand && node.HadChildrenBeforePopulating)
// throw new InvalidOperationException ("PopulateOnDemand cannot be set to true on a node that already has children.");
DecorateNode(node);
string nodeImage;
bool clientExpand = EnableClientScript && Events [TreeNodeCollapsedEvent] == null && Events [TreeNodeExpandedEvent] == null;
ImageStyle imageStyle = GetImageStyle ();
bool renderChildNodes = node.Expanded.HasValue && node.Expanded.Value;
if (clientExpand && !renderChildNodes)
renderChildNodes = (!node.PopulateOnDemand || node.Populated);
bool hasChildNodes;
if (renderChildNodes)
hasChildNodes = node.ChildNodes.Count > 0;
else
hasChildNodes = (node.PopulateOnDemand && !node.Populated) || node.ChildNodes.Count > 0;
writer.AddAttribute (HtmlTextWriterAttribute.Cellpadding, "0", false);
writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, "0", false);
writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
writer.RenderBeginTag (HtmlTextWriterTag.Table);
#if !NET_4_0
Unit nodeSpacing = GetNodeSpacing (node);
if (nodeSpacing != Unit.Empty && (node.Depth > 0 || node.Index > 0))
RenderMenuItemSpacing (writer, nodeSpacing);
#endif
writer.RenderBeginTag (HtmlTextWriterTag.Tr);
// Vertical lines from previous levels
nodeImage = GetNodeImageUrl ("i", imageStyle);
for (int n=0; n<level; n++) {
writer.RenderBeginTag (HtmlTextWriterTag.Td);
writer.AddStyleAttribute (HtmlTextWriterStyle.Width, NodeIndent + "px");
writer.AddStyleAttribute (HtmlTextWriterStyle.Height, "1px");
writer.RenderBeginTag (HtmlTextWriterTag.Div);
if (ShowLines && levelLines [n] != null) {
writer.AddAttribute (HtmlTextWriterAttribute.Src, nodeImage);
writer.AddAttribute (HtmlTextWriterAttribute.Alt, String.Empty, false);
writer.RenderBeginTag (HtmlTextWriterTag.Img);
writer.RenderEndTag ();
}
writer.RenderEndTag ();
writer.RenderEndTag (); // TD
}
// Node image + line
bool showExpandCollapse = ShowExpandCollapse;
bool showLines = ShowLines;
if (showExpandCollapse || showLines) {
bool buttonImage = false;
string tooltip = String.Empty;
string shape = String.Empty;
if (showLines) {
if (hasPrevious && hasNext)
shape = "t";
else if (hasPrevious && !hasNext)
shape = "l";
else if (!hasPrevious && hasNext)
shape = "r";
else
shape = "dash";
}
if (showExpandCollapse) {
if (hasChildNodes) {
buttonImage = true;
if (node.Expanded.HasValue && node.Expanded.Value)
shape += "minus";
else
shape += "plus";
tooltip = GetNodeImageToolTip (!(node.Expanded.HasValue && node.Expanded.Value), node.Text);
} else if (!showLines)
shape = "noexpand";
}
if (!String.IsNullOrEmpty (shape)) {
nodeImage = GetNodeImageUrl (shape, imageStyle);
writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
if (buttonImage) {
if (!clientExpand || (!PopulateNodesFromClient && node.PopulateOnDemand && !node.Populated))
writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientEvent (node, "ec"));
else
writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientExpandEvent(node));
writer.RenderBeginTag (HtmlTextWriterTag.A); // Anchor
}
// tooltip is 'HtmlAttributeEncoded'
writer.AddAttribute (HtmlTextWriterAttribute.Alt, tooltip);
if (buttonImage && clientExpand)
writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "img"));
writer.AddAttribute (HtmlTextWriterAttribute.Src, nodeImage);
if (buttonImage)
writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
writer.RenderBeginTag (HtmlTextWriterTag.Img);
writer.RenderEndTag ();
if (buttonImage)
writer.RenderEndTag (); // Anchor
writer.RenderEndTag (); // TD
}
}
// Node icon
string imageUrl = node.ImageUrl.Length > 0 ? ResolveClientUrl (node.ImageUrl) : null;
if (String.IsNullOrEmpty (imageUrl) && imageStyle != null) {
if (imageStyle.RootIcon != null && node.IsRootNode)
imageUrl = GetNodeIconUrl (imageStyle.RootIcon);
else if (imageStyle.ParentIcon != null && node.IsParentNode)
imageUrl = GetNodeIconUrl (imageStyle.ParentIcon);
else if (imageStyle.LeafIcon != null && node.IsLeafNode)
imageUrl = GetNodeIconUrl (imageStyle.LeafIcon);
}
if (level < LevelStyles.Count && LevelStyles [level].ImageUrl != null)
imageUrl = ResolveClientUrl (LevelStyles [level].ImageUrl);
if (!String.IsNullOrEmpty (imageUrl)) {
writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
#if NET_4_0
writer.AddAttribute (HtmlTextWriterAttribute.Tabindex, "-1");
#endif
BeginNodeTag (writer, node, clientExpand);
writer.AddAttribute (HtmlTextWriterAttribute.Src, imageUrl);
writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
writer.AddAttribute (HtmlTextWriterAttribute.Alt, node.ImageToolTip);
writer.RenderBeginTag (HtmlTextWriterTag.Img);
writer.RenderEndTag (); // IMG
writer.RenderEndTag (); // style tag
writer.RenderEndTag (); // TD
}
if (!NodeWrap)
writer.AddStyleAttribute (HtmlTextWriterStyle.WhiteSpace, "nowrap");
bool nodeIsSelected = node == SelectedNode && selectedNodeStyle != null;
if (!nodeIsSelected && selectedNodeStyle != null) {
if (!String.IsNullOrEmpty (activeSiteMapPath))
nodeIsSelected = String.Compare (activeSiteMapPath, node.NavigateUrl, RuntimeHelpers.StringComparison) == 0;
}
AddNodeStyle (writer, node, level, nodeIsSelected);
if (EnableClientScript) {
writer.AddAttribute ("onmouseout", "TreeView_UnhoverNode(this)", false);
writer.AddAttribute ("onmouseover", "TreeView_HoverNode('" + ClientID + "', this)");
}
writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
// Checkbox
if (node.ShowCheckBoxInternal) {
writer.AddAttribute (HtmlTextWriterAttribute.Name, ClientID + "_cs_" + node.Path);
writer.AddAttribute (HtmlTextWriterAttribute.Type, "checkbox", false);
#if NET_4_0
string str = node.ToolTip;
if (!String.IsNullOrEmpty (str))
writer.AddAttribute (HtmlTextWriterAttribute.Title, str);
#else
writer.AddAttribute (HtmlTextWriterAttribute.Title, node.Text);
#endif
if (node.Checked)
writer.AddAttribute (HtmlTextWriterAttribute.Checked, "checked", false);
writer.RenderBeginTag (HtmlTextWriterTag.Input); // INPUT
writer.RenderEndTag (); // INPUT
}
// Text
node.BeginRenderText (writer);
if (clientExpand)
writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "txt"));
AddNodeLinkStyle (writer, node, level, nodeIsSelected);
BeginNodeTag (writer, node, clientExpand);
writer.Write (node.Text);
writer.RenderEndTag (); // style tag
node.EndRenderText (writer);
writer.RenderEndTag (); // TD
writer.RenderEndTag (); // TR
#if !NET_4_0
if (nodeSpacing != Unit.Empty)
RenderMenuItemSpacing (writer, nodeSpacing);
#endif
writer.RenderEndTag (); // TABLE
// Children
if (hasChildNodes) {
if (level >= levelLines.Count) {
if (hasNext)
levelLines.Add (this);
else
levelLines.Add (null);
} else {
if (hasNext)
levelLines [level] = this;
else
levelLines [level] = null;
}
if (clientExpand) {
if (!(node.Expanded.HasValue && node.Expanded.Value))
writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "none");
else
writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "block");
writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, null));
writer.RenderBeginTag (HtmlTextWriterTag.Span);
if (renderChildNodes) {
AddChildrenPadding (writer, node);
int num = node.ChildNodes.Count;
for (int n=0; n<num; n++)
RenderNode (writer, node.ChildNodes [n], level + 1, levelLines, true, n<num-1);
if (hasNext)
AddChildrenPadding (writer, node);
}
writer.RenderEndTag (); // SPAN
} else if (renderChildNodes) {
AddChildrenPadding (writer, node);
int num = node.ChildNodes.Count;
for (int n=0; n<num; n++)
RenderNode (writer, node.ChildNodes [n], level + 1, levelLines, true, n<num-1);
if (hasNext)
AddChildrenPadding (writer, node);
}
}
}