📄 supertreeview.cs
字号:
e.MoveType = NodeMoveType.NodeMoveRight;
e.node = NodeToBeCut;
e.PrevPath = NodeToBeCutPath + "\\";
SuperTreeViewNode tmpNode = NodeToBeCut;
this.NodeMove(tmpNode,e);
this.NodeToBeCut = null;
this.NodeToBeCutPath = "";
}
#endregion
#endregion
#region XML支持
/*给TreeView加上XML功能
*
*对外接口
*/
/// <summary>
/// 从XML文件中装入,如果指定了rootNode,则XML文件中的树节点成为rootNode的子树,否则,导入的节点独立成为一棵树
/// </summary>
/// <param name="filename"></param>
/// <param name="rootNode"></param>
public void LoadFromXMLFile(string filename,SuperTreeViewNode rootNode)
{
XmlDocument dom = new XmlDocument();
try
{
dom.Load(filename);
this.CreateTree(dom,rootNode);
}
catch(Exception ex)
{
throw new Exception("装入XML文件:" + filename + "生成树时出错,在SuperTreeView.LoadFromXMLFile中,下次对象返回信息:" + ex.Message);
}
}
/// <summary>
/// 从XML字串中装入,如果指定了rootNode,则XML文件中的树节点成为rootNode的子树,否则,导入的节点独立成为一棵树
/// </summary>
/// <param name="xmlstr"></param>
/// <param name="rootNode"></param>
public void LoadFromXMLStr(string xmlstr,TreeNode rootNode)
{
XmlDocument dom = new XmlDocument();
try
{
dom.LoadXml(xmlstr);
this.CreateTree(dom,rootNode as SuperTreeViewNode);
}
catch(Exception ex)
{
throw new Exception("装入XML字串生成树时出错,在SuperTreeView.LoadFromXMLStr中,下次对象返回信息:" + ex.Message);
}
}
/// <summary>
/// 将树保存到XML文件中,如果指定了rootNode,则只导出此子树,否则,导出全树
/// </summary>
/// <param name="filename"></param>
/// <param name="rootNode"></param>
/// <returns></returns>
public bool SaveToXMLFile(string filename,TreeNode rootNode)
{
XmlDocument dom = new XmlDocument();
string xmlStr;
try
{
xmlStr = this.SaveToXMLStr(rootNode);
if(xmlStr == "")
{
//创建一个最基本的根元素
xmlStr = @"<个人信息管理器 NodeType=""OnlyText"" />";
}
dom.LoadXml(xmlStr);
dom.Save(filename);
return true;
}
catch(Exception ex)
{
throw new Exception("向XML文件:" + filename + "导出树结构时出错,在SuperTreeView.SaveToXMLFile中,下次对象返回信息:" + ex.Message);
}
}
/// <summary>
/// 将树保存到XML字串中,如果指定了rootNode,则只导出此子树,否则,导出全树
/// </summary>
/// <param name="rootNode"></param>
/// <returns></returns>
public string SaveToXMLStr(TreeNode rootNode)
{
XmlDocument dom = new XmlDocument();
XmlElement xmlroot;
try
{
if(this.GetNodeCount(true) == 0)
return "";
if(rootNode == null)
rootNode = this.Nodes[0];
//创建DOM子树根节点
xmlroot = this.CreateXMLNodeFromTreeNode(rootNode,dom) as XmlElement;
dom.AppendChild(xmlroot);
//将子树节点加入到DOM树中
this.AddTreeNodeToXML(rootNode,xmlroot,dom);
return dom.OuterXml;
}
catch(Exception ex)
{
throw new Exception("将树保存到XML字串时出错,在SuperTreeView.SaveToXMLStr中,下次对象返回信息:" + ex.Message);
}
}
/*
* 支持函数
*/
/// <summary>
/// 将树节点保存到DOM树中的对应节点下
/// </summary>
/// <param name="tNode"></param>
/// <param name="xNode"></param>
/// <param name="dom"></param>
private void AddTreeNodeToXML(TreeNode tNode,XmlNode xNode,XmlDocument dom)
{
XmlElement tmpXMLNode;
if(tNode.GetNodeCount(false) > 0)
{
foreach(TreeNode tmpTreeNode in tNode.Nodes)
{
tmpXMLNode = this.CreateXMLNodeFromTreeNode(tmpTreeNode,dom) as XmlElement;
//将新节点加入DOM树
xNode.AppendChild(tmpXMLNode);
//递归调用
this.AddTreeNodeToXML(tmpTreeNode,tmpXMLNode,dom);
}
}
}
/// <summary>
/// 从XMLNode节点创建SuperTreeViewNode
/// </summary>
/// <param name="xNode"></param>
/// <returns></returns>
private SuperTreeViewNode CreateSuperTreeViewNodeFromXMLNode(XmlNode xNode)
{
if(xNode == null)
throw new Exception("不能转换为null的XML节点,在SuperTreeView.CreateSuperTreeViewNodeFromXMLNode中抛出异常.");
string NodeText;
//If the element has a value, display it;
//otherwise display the element name
if(xNode.Value != null)
NodeText = xNode.Value;
else
NodeText = xNode.Name;
//检查一下是否存在Title属性,如果有,则将其值取出作为树节点值
XmlAttribute xAttr = xNode.Attributes["Title"];
if(xAttr != null)
NodeText = xAttr.Value;
SuperTreeViewNode tmpNode = new SuperTreeViewNode(NodeText);
xAttr = xNode.Attributes["NodeType"];
if(xAttr != null)
tmpNode.NodeType = xAttr.Value;
//支持图标
xAttr = xNode.Attributes["ImageIndex"];
if(xAttr != null)
tmpNode.ImageIndex = int.Parse(xAttr.Value);
//支持图标
xAttr = xNode.Attributes["SelectedImageIndex"];
if(xAttr != null)
tmpNode.SelectedImageIndex = int.Parse(xAttr.Value);
return tmpNode;
}
/// <summary>
/// 将SuperTreeViewNode转为XMLNode
/// </summary>
/// <param name="tNode"></param>
/// <param name="dom"></param>
/// <returns></returns>
private XmlNode CreateXMLNodeFromTreeNode(TreeNode tNode,XmlDocument dom)
{
XmlElement tmpXmlNode;
SuperTreeViewNode tmpSuperTreeViewNode = null;
if(tNode.GetType().Name == "SuperTreeViewNode")
{
tmpSuperTreeViewNode = tNode as SuperTreeViewNode;
}
tmpXmlNode = dom.CreateElement("TreeNode");
tmpXmlNode.SetAttribute("Title",tNode.Text);
if(tmpSuperTreeViewNode != null)
{
//保存NodeType属性
if(tmpSuperTreeViewNode.NodeType != "")
{
tmpXmlNode.SetAttribute("NodeType",tmpSuperTreeViewNode.NodeType);
}
}
//保存图标设置
if(tNode.ImageIndex > -1)
{
tmpXmlNode.SetAttribute("ImageIndex",tNode.ImageIndex.ToString());
}
if(tNode.SelectedImageIndex > -1)
{
tmpXmlNode.SetAttribute("SelectedImageIndex",tNode.SelectedImageIndex.ToString());
}
return tmpXmlNode;
}
/// <summary>
/// 从Dom对象创建树,同时创建用于快速搜索的HashTable集合和DataTable
/// </summary>
/// <param name="xNode"></param>
/// <param name="tNode"></param>
private void AddXMLNodeToTree(XmlNode xNode,TreeNode tNode)
{
if(xNode == null || tNode == null)
throw new Exception("Should Give an valid XML DOM Node or TreeNode!");
SuperTreeViewNode new_child;
foreach(XmlNode node in xNode.ChildNodes)
{
//屏蔽注释节点
if(node.NodeType != XmlNodeType.Comment)
{
new_child = this.CreateSuperTreeViewNodeFromXMLNode(node);
//向树中加入节点
tNode.Nodes.Add(new_child);
if(this.TreeNodes.Contains(new_child.FullPath) == false)
{
this.TreeNodes.Add(new_child.FullPath,new_child);
this.AddNodeToDataTable(new_child);
}
//递归处理树节点
this.AddXMLNodeToTree(node,new_child);
}
}
}
private void CreateTree(XmlDocument dom,SuperTreeViewNode rootNode)
{
//获取XML树的根节点
XmlNode xmlroot = dom.DocumentElement;
if(xmlroot == null)
return;
//创建树的根节点
SuperTreeViewNode tmpNode = this.CreateSuperTreeViewNodeFromXMLNode(xmlroot);
if(rootNode == null)//没有指定树的根节点,重新创建一棵树
{
//清空原有树
this.Nodes.Clear();
this.TreeNodes.Clear();
this.dtTreeNodes.Rows.Clear();
this.Nodes.Add(tmpNode);
//加入树节点集合
if(this.TreeNodes.Contains(tmpNode.FullPath) == false)
{
this.TreeNodes.Add(tmpNode.FullPath,tmpNode);
//加入DataTable
this.AddNodeToDataTable(tmpNode);
}
}
else
{
rootNode.Nodes.Add(tmpNode);
if(this.TreeNodes.Contains(tmpNode.FullPath) == false)
{
this.TreeNodes.Add(tmpNode.FullPath,tmpNode);
//加入DataTable
this.AddNodeToDataTable(tmpNode);
}
}
//XML DOM树移入TreeView
this.AddXMLNodeToTree(xmlroot,tmpNode);
}
#endregion
private bool _autoExpandSubTree = false;
/// <summary>
/// 用户单击节点时是否展开子树
/// </summary>
public bool AutoExpandSubTree
{
get
{
return _autoExpandSubTree;
}
set
{
_autoExpandSubTree = value;
}
}
/// <summary>
/// 根据指定节点,生成表示此节点的路径
/// </summary>
/// <param name="node"></param>
/// <param name="IgnoreRootNode">是否忽略根节点</param>
/// <param name="devider">表示分隔符</param>
/// <returns></returns>
public string GetNodePathStr(TreeNode node, bool IgnoreRootNode, string devider)
{
if(node == null)
return "";
ArrayList strArr = new ArrayList();
//处理根节点
if(node.Parent == null)
{
if(IgnoreRootNode)
return "";
else
return node.Text;
}
//用堆栈来存储路径节点字串
Stack pathStack = new Stack();
string strPath = "";
pathStack.Push(node.Text);
while(!(node.Parent == null))
{
pathStack.Push(node.Parent.Text);
node = node.Parent;
}
int count = pathStack.Count;
if(IgnoreRootNode)
{
for(int i=0; i<count; i++)
{
if(i > 0)
{
if(i == 1)
{
strPath = pathStack.Pop().ToString();
}
else
{
strPath = strPath + devider + pathStack.Pop().ToString();
}
}
else
{
pathStack.Pop();
}
}
}
else
{
for(int i=0; i<count; i++)
{
if(i > 0)
{
strPath = strPath + devider + pathStack.Pop().ToString();
}
else
{
strPath = pathStack.Pop().ToString();
}
}
}
return strPath;
}
/// <summary>
/// 按照完整路径在树中搜索节点
/// </summary>
/// <param name="nodePath"></param>
/// <returns></returns>
public SuperTreeViewNode FindNode(string nodePath)
{
return this.TreeNodes[nodePath] as SuperTreeViewNode;
}
private void SuperTreeView_AfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e)
{
//先找到所有此节点的子树节点的记录
if(e.Label == null || e.Label == e.Node.Text)
return;
DataRow[] drs = this.dtTreeNodes.Select("NodePath Like '" + e.Node.FullPath + "%'");
string str, oldPath, newPath;
//先把原路径截去本节点Text
str = e.Node.FullPath.Substring(0, e.Node.FullPath.Length - e.Node.Text.Length);
//合并组成新节点路径
str = str + e.Label;
SuperTreeViewNode node;
foreach( DataRow dr in drs)
{
oldPath = dr["NodePath"].ToString();
//替换掉原路径
newPath = str + oldPath.Substring(0, oldPath.Length - e.Node.FullPath.Length);
//记录下节点引用
node = this.TreeNodes[oldPath] as SuperTreeViewNode;
//移除节点
this.TreeNodes.Remove(oldPath);
//再加入新节点
if(this.TreeNodes.Contains(newPath) == false)
{
this.TreeNodes.Add(newPath, node);
//更新数据集中记录
dr["NodePath"] = newPath;
}
}
}
/// <summary>
/// 获取特定节点的层数,从0开始,出错返回-1
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public int GetNodeLevel(TreeNode node)
{
if(node == null)
return -1;
if(node.Parent == null)
return 0;
int level = 0;
TreeNode tmpnode = node.Parent;
while(tmpnode != null)
{
level ++;
tmpnode = tmpnode.Parent;
}
return level;
}
/// <summary>
/// 获取特定节点的在兄弟中的索引,从0开始,出错返回-1
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public int GetNodeIndexInBrothers(TreeNode node)
{
if(node == null)
return -1;
TreeNode tmpNode = node.PrevNode;
int index = 0;
while(!(tmpNode == null))
{
index ++;
tmpNode = tmpNode.PrevNode;
}
return index;
}
private void SuperTreeView_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
if(this._autoExpandSubTree)
{
if(this.SelectedNode != null)
{
this.SelectedNode.Expand();
}
}
}
}
/// <summary>
/// 节点移动事件参数
/// </summary>
public class NodeMoveEventArgs : System.EventArgs
{
//被操作的节点
public SuperTreeViewNode node;
//节点移动前的路径
public string PrevPath;
//节点移动类型
public NodeMoveType MoveType;
}
/// <summary>
/// 定义节点移动类型
/// </summary>
public enum NodeMoveType
{
NodeMoveUp,//节点上移
NodeMoveDown,//节点下移
NodeMoveLeft,//节点左移,升级
NodeMoveRight//节点右移,降级
}
public class SuperTreeViewNode : System.Windows.Forms.TreeNode
{
//节点类型
public string NodeType = "";
public static int NodeCount = 0;
public SuperTreeViewNode(string NodeText) : base(NodeText)
{
NodeCount++;
}
public SuperTreeViewNode() : base()
{
NodeCount++;
}
/// <summary>
/// 获取完整路径,其后以"\"结束
/// </summary>
public new string FullPath
{
get
{
return base.FullPath + @"\";
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -