treenode.cs
来自「浏览器端看到树型目录结构,用户可以完整地看到像windows资源管理器一样的效果」· CS 代码 · 共 1,240 行 · 第 1/3 页
CS
1,240 行
CheckedExpandable = false;
}
}
/// <summary>
/// Returns a reference to the parent TreeView.
/// </summary>
protected internal TreeView ParentTreeView
{
get
{
if (_treeview == null)
{
// Get the parent treeview
TreeNode prev = this;
while (prev.Parent is TreeNode)
prev = (TreeNode)prev.Parent;
_treeview = (TreeView)prev.Parent;
}
return _treeview;
}
set
{
_treeview = value;
foreach (TreeNode node in Nodes)
{
node.ParentTreeView = value;
}
}
}
/// <summary>
/// Returns the level in the tree.
/// </summary>
protected int Level
{
get
{
if (_level == -1)
{
Object prev = Parent;
while (prev is TreeNode)
{
prev = ((TreeNode)prev).Parent;
_level++;
}
return ++_level;
}
else
return _level;
}
}
/// <summary>
/// Returns the number of sibling TreeNodes before this one.
/// </summary>
internal int SibIndex
{
get
{
if (Parent != null)
{
if (Parent is TreeNode)
return ((TreeNode)Parent).Nodes.IndexOf(this);
else
return ((TreeView)Parent).Nodes.IndexOf(this);
}
else
return -1;
}
/*
if (_sibIndex == -1)
{
TreeNode node = this;
while (node != null)
{
_sibIndex++;
node = node.GetPreviousSibling();
}
}
return _sibIndex;
}
set
{
_sibIndex = value;
}
*/
}
/// <summary>
/// Gets the collection of nodes in the control.
/// </summary>
[
Category("Data"),
DefaultValue(null),
MergableProperty(false),
Browsable(false),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
ResDescription("TreeNodes"),
]
public virtual TreeNodeCollection Nodes
{
get { return _Nodes; }
}
/// <summary>
/// Initializes a new instance of a TreeNode.
/// </summary>
public TreeNode() : base()
{
_level = -1;
_treeview = null;
_strInheritedType = null;
_NodeTypeIndex = -1;
_bBound = false;
_Nodes = new TreeNodeCollection(this);
}
/// <summary>
/// Event handler for the OnSelectedIndexChange event.
/// </summary>
/// <param name="e">Event arguments</param>
/// <returns>true to bubble, false to cancel</returns>
protected virtual bool OnSelectedIndexChange(EventArgs e)
{
return true;
}
/// <summary>
/// Event handler for the OnExpand event.
/// </summary>
/// <param name="e">Event arguments</param>
/// <returns>true to bubble, false to cancel</returns>
protected virtual bool OnExpand(EventArgs e)
{
if (!Expanded && CanExpand())
{
Expanded = true;
Object obj = FindNodeAttribute("Expandable");
if (obj == null)
{
obj = Expandable; // get default value if none is explicitly set
}
if ((ExpandableValue)obj == ExpandableValue.CheckOnce)
CheckedExpandable = true;
if (!_bBound)
ReadXmlSrc();
return true;
}
else
return false;
}
/// <summary>
/// Event handler for the OnCollapse event.
/// </summary>
/// <param name="e">Event arguments</param>
/// <returns>true to bubble, false to cancel</returns>
protected virtual bool OnCollapse(EventArgs e)
{
if (Expanded)
{
Expanded = false;
// If this node was selected, unselect it and make the parent the selected node
// Note: The client handles this nicely uplevel; we only need to do this downlevel
if (! ParentTreeView.IsUpLevel)
{
String strNewIndex = GetNodeIndex();
String strOldIndex = ParentTreeView.SelectedNodeIndex;
if (strOldIndex.StartsWith(strNewIndex) && strOldIndex != strNewIndex)
{
TreeViewSelectEventArgs e2 = new TreeViewSelectEventArgs(strOldIndex, strNewIndex);
ParentTreeView.DoSelectedIndexChange(e2);
// Since this only gets called downlevel, we don't need to worry about other selection
// changes being queued-- this will be the only one, and so we can queue an event for it
ParentTreeView._eventList.Add("s");
ParentTreeView._eventList.Add(e2);
}
}
return true;
}
else
return false;
}
//
// OnCheck
//
/// <summary>
/// Event handler for OnCheck event
/// </summary>
protected virtual bool OnCheck(EventArgs e)
{
Checked = !Checked;
return true;
}
//
// OnInit
//
/// <summary>
/// Initializes the TreeNode.
/// </summary>
internal void OnInit()
{
if (Expanded)
{
Databind();
}
}
/// <summary>
/// Process the event string, calling the appropriate event handler.
/// </summary>
/// <param name="eventArg">Event argument.</param>
/// <returns>true to bubble, false otherwise.</returns>
private bool ProcessEvent(string eventArg)
{
int nSep = eventArg.IndexOf(',');
if (nSep < 0)
nSep = eventArg.Length;
string strEvent = eventArg.Substring(0, nSep);
EventArgs e = new EventArgs();
if (strEvent.Equals("onexpand"))
return OnExpand(e);
else if (strEvent.Equals("oncollapse"))
return OnCollapse(e);
else if (strEvent.Equals("onselectedindexchange"))
return OnSelectedIndexChange(e);
else if (strEvent.Equals("oncheck"))
return OnCheck(e);
else
return false;
}
/// <summary>
/// Public entry point used by treeview to "bubble down" an event, thus freeing treenodes from having
/// to include postback HTML for default treenode activity
/// </summary>
/// <param name="eventArg">Event argument.</param>
internal virtual void LowerPostBackEvent(string eventArg)
{
ProcessEvent(eventArg);
}
/// <summary>
/// Sets all items within the StateBag to be dirty
/// </summary>
protected internal override void SetViewStateDirty()
{
base.SetViewStateDirty();
Nodes.SetViewStateDirty();
}
/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
/// <returns>A new object that is a copy of this instance.</returns>
public override object Clone()
{
TreeNode copy = (TreeNode)base.Clone();
copy._strInheritedType = this._strInheritedType;
copy._NodeTypeIndex = -1;
copy._Nodes = (TreeNodeCollection)this._Nodes.Clone();
// Fix parentage
copy._Nodes.Parent = copy;
if (copy._Nodes.Count > 0)
{
foreach (TreeNode tnode in copy._Nodes)
{
tnode._Parent = copy;
}
}
return copy;
}
/// <summary>
/// Renders the node for uplevel browsers.
/// </summary>
/// <param name="output">The HtmlTextWriter object that receives the content.</param>
protected override void RenderUpLevelPath(HtmlTextWriter output)
{
if (Type != String.Empty)
output.AddAttribute("Type", Type);
if (Expandable == ExpandableValue.CheckOnce)
output.AddAttribute("Expandable", "checkOnce");
else if (Expandable == ExpandableValue.Always)
output.AddAttribute("Expandable", "always");
if (CheckedExpandable)
output.AddAttribute("checkedExpandable", "true");
// Because of ExpandLevel, we need to distinguish between explicitly-declared false and default false.
// Only the explicit false will be stored in ViewState.
object b = ViewState["Expanded"];
if (Expanded || (b != null && (bool)b == false))
output.AddAttribute("Expanded", Expanded.ToString());
if (Selected)
output.AddAttribute("Selected", "true");
if (NavigateUrl != String.Empty)
output.AddAttribute("NavigateUrl", NavigateUrl);
if (Checked)
output.AddAttribute("Checked", "true");
if (NodeData != String.Empty)
output.AddAttribute("NodeData", NodeData);
AddAttributesToRender(output);
output.RenderBeginTag("tvns:treenode");
if (Text != String.Empty)
output.Write(Text);
base.RenderUpLevelPath(output);
// Render contained nodes
foreach (TreeNode node in Nodes)
node.Render(output, RenderPathID.UpLevelPath);
output.RenderEndTag();
}
/// <summary>
/// Returns the node's previous TreeNode sibling, or null
/// </summary>
/// <returns>The node's previous TreeNode sibling, or null.</returns>
protected TreeNode GetPreviousSibling()
{
TreeNodeCollection sibs;
if (Parent is TreeNode)
sibs = ((TreeNode)Parent).Nodes;
else
sibs = ((TreeView)Parent).Nodes;
int iIndex = sibs.IndexOf(this) - 1;
if (iIndex >= 0)
return sibs[iIndex];
else
return null;
}
/// <summary>
/// Returns a x.y.z format node index string representing the node's position in the hierarchy.
/// </summary>
/// <returns>The x.y.z formatted index.</returns>
public string GetNodeIndex()
{
string strIndex = "";
Object node = this;
while (node is TreeNode)
{
if (((TreeNode)node).SibIndex == -1)
return String.Empty;
if (strIndex.Length == 0)
strIndex = ((TreeNode)node).SibIndex.ToString();
else
strIndex = ((TreeNode)node).SibIndex.ToString() + "." + strIndex;
node = ((TreeNode)node).Parent;
}
return strIndex;
}
/// <summary>
/// Determine if the current node is an L, T, or Root junction.
/// Note: This code is essentially duplicated from the client behavior.
/// </summary>
/// <returns>A character defining the type of junction.</returns>
protected char CalcJunction()
{
if (Parent is TreeView && GetPreviousSibling() == null)
{
// Get index of node and add 1 to the last value
string strIndex = GetNodeIndex();
int iIndexPos = strIndex.LastIndexOf('.');
int iIndexVal = Convert.ToInt32(strIndex.Substring(iIndexPos + 1)) + 1;
strIndex = strIndex.Substring(0,iIndexPos + 1) + iIndexVal.ToString();
// if the node exists, we're an "F" node.
if (ParentTreeView.GetNodeFromIndex(strIndex) != null)
return 'F';
else
return 'R';
}
else
{
TreeNodeCollection col;
if (Parent is TreeView)
col = ((TreeView)Parent).Nodes;
else
col = ((TreeNode)Parent).Nodes;
int i = col.IndexOf(this) + 1;
if (i < col.Count)
return 'T';
return 'L';
}
}
/// <summary>
/// Renders the designer version of the TreeNode, which is the downlevel version.
/// </summary>
/// <param name="output">The HtmlTextWriter that will receive that markup.</param>
protected override void RenderDesignerPath(HtmlTextWriter output)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?