📄 supertreeview.cs
字号:
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Xml;
namespace PublicUIComponent
{
/// <summary>
/// SuperTreeView 的摘要说明。
/// </summary>
public class SuperTreeView : System.Windows.Forms.TreeView
{
#region Windows 窗体设计器生成的代码
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public SuperTreeView()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
Init();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
//
// SuperTreeView
//
this.Size = new System.Drawing.Size(300, 300);
this.Text = "SuperTreeView";
this.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.SuperTreeView_AfterSelect);
this.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.SuperTreeView_AfterLabelEdit);
}
#endregion
#region 变量区
//存放树节点,用于检索树节点
public Hashtable TreeNodes = new Hashtable();
//此DataTable与TreeNodes对应,用于提供类似SQL命令的搜索功能
public DataTable dtTreeNodes;
#endregion
/// <summary>
/// 初始化
/// </summary>
private void Init()
{
//创建用于检索树节点的DataTable
DataColumn dc = new DataColumn("NodePath",typeof(string));
dtTreeNodes = new DataTable("TreeNodes");
dtTreeNodes.Columns.Add(dc);
}
public delegate void NodeMoveEventHandler(object sender,NodeMoveEventArgs e);
/// <summary>
/// 节点移动事件
/// </summary>
public event NodeMoveEventHandler NodeMove;
#region 树节点操作
/// <summary>
/// 增加一级节点
/// </summary>
/// <returns></returns>
public SuperTreeViewNode AddFirstLevelNode()
{
SuperTreeViewNode node = new SuperTreeViewNode("新节点" + SuperTreeViewNode.NodeCount.ToString());
this.Nodes.Add(node);
this.SelectedNode = node;
//更新节点集合和记录集
if(this.TreeNodes.Contains(node.FullPath) == false)
{
this.TreeNodes.Add(node.FullPath,node);
this.AddNodeToDataTable(node);
}
return node;
}
/// <summary>
/// 增加一级节点
/// </summary>
/// <returns></returns>
public SuperTreeViewNode AddFirstLevelNode(string NodeText)
{
SuperTreeViewNode node = new SuperTreeViewNode(NodeText);
this.Nodes.Add(node);
this.SelectedNode = node;
//更新节点集合和记录集
if(this.TreeNodes.Contains(node.FullPath) == false)
{
this.TreeNodes.Add(node.FullPath,node);
this.AddNodeToDataTable(node);
}
return node;
}
/// <summary>
/// 增加新子节点
/// </summary>
/// <returns></returns>
public SuperTreeViewNode AddSelectedNodeChild()
{
if(this.SelectedNode == null)
return null;
SuperTreeViewNode tmpnode = new SuperTreeViewNode("新节点" + SuperTreeViewNode.NodeCount.ToString());
this.SelectedNode.Nodes.Add(tmpnode);
this.SelectedNode = tmpnode;
//更新节点集合和记录集
if(this.TreeNodes.Contains(tmpnode.FullPath))
{
this.TreeNodes.Add(tmpnode.FullPath,tmpnode);
this.AddNodeToDataTable(tmpnode);
}
return tmpnode;
}
/// <summary>
/// 增加新子节点
/// </summary>
/// <returns></returns>
public SuperTreeViewNode AddSelectedNodeChild(string NodeText)
{
if(this.SelectedNode == null)
return null;
SuperTreeViewNode tmpnode = new SuperTreeViewNode(NodeText);
this.SelectedNode.Nodes.Add(tmpnode);
this.SelectedNode = tmpnode;
//更新节点集合和记录集
if(this.TreeNodes.Contains(tmpnode.FullPath))
{
this.TreeNodes.Add(tmpnode.FullPath,tmpnode);
this.AddNodeToDataTable(tmpnode);
}
return tmpnode;
}
/// <summary>
/// 增加兄弟节点
/// </summary>
/// <returns></returns>
public SuperTreeViewNode AddSelectedNodeBrother()
{
if(this.SelectedNode == null || this.SelectedNode.Parent == null)
return null;
SuperTreeViewNode tmpnode = new SuperTreeViewNode("新节点" + SuperTreeViewNode.NodeCount.ToString());
this.SelectedNode.Parent.Nodes.Add(tmpnode);
this.SelectedNode = tmpnode;
//更新节点集合和记录集
if(this.TreeNodes.Contains(tmpnode.FullPath))
{
this.TreeNodes.Add(tmpnode.FullPath,tmpnode);
this.AddNodeToDataTable(tmpnode);
}
return tmpnode;
}
/// <summary>
/// 增加兄弟节点
/// </summary>
/// <returns></returns>
public SuperTreeViewNode AddSelectedNodeBrother(string NodeText)
{
if(this.SelectedNode == null || this.SelectedNode.Parent == null)
return null;
SuperTreeViewNode tmpnode = new SuperTreeViewNode(NodeText);
if(this.SelectedNode.Parent == null)
this.Nodes.Add(tmpnode);
else
this.SelectedNode.Parent.Nodes.Add(tmpnode);
this.SelectedNode = tmpnode;
//更新节点集合和记录集
if(this.TreeNodes.Contains(tmpnode.FullPath))
{
this.TreeNodes.Add(tmpnode.FullPath,tmpnode);
this.AddNodeToDataTable(tmpnode);
}
return this.SelectedNode as SuperTreeViewNode;
}
/// <summary>
/// 删除选中的节点
/// </summary>
public void DeleteSelectedNode()
{
this.DeleteSelectedNodeAndIndex(true);
}
/// <summary>
/// 实际完成删除工作,可以选择是否同步删除索引信息(HashTable和DataTable中)
/// </summary>
/// <param name="DeleteIndex"></param>
private void DeleteSelectedNodeAndIndex(bool DeleteIndex)
{
if(this.SelectedNode == null)
return;
//删除索引信息
if(DeleteIndex)
this.DeleteNodeIndexInfo((this.SelectedNode as SuperTreeViewNode).FullPath);
//从树中清除节点
this.Nodes.Remove(this.SelectedNode);
this.SelectedNode = null;
}
/// <summary>
/// 删除指定路径下的索引信息
/// </summary>
/// <param name="NodePath"></param>
private void DeleteNodeIndexInfo(string NodePath)
{
//从节点索引集合中移除
DataRow[] drs = this.dtTreeNodes.Select("NodePath Like '" + NodePath + "%'");
foreach(DataRow dr in drs)
{
this.TreeNodes.Remove(dr["NodePath"]);
this.dtTreeNodes.Rows.Remove(dr);
}
}
/// <summary>
/// 更改选中节点的文本
/// </summary>
private void RenameSelectedNode()
{
if(this.SelectedNode == null)
return;
if(this.LabelEdit)
{
this.SelectedNode.BeginEdit();
}
}
/// <summary>
/// 将一个树节点加入到DataTable中,此节点必须已经被加入到树中
/// </summary>
/// <param name="tNode"></param>
private void AddNodeToDataTable(TreeNode tNode)
{
if(tNode == null)
return;
if(tNode.TreeView == null)
throw new Exception("TreeNode should have been added to TreeView before it can be added to DataTable !");
DataRow dr = dtTreeNodes.NewRow();
dr["NodePath"] = tNode.FullPath + @"\";
dtTreeNodes.Rows.Add(dr);
}
#endregion
#region 树节点移动
/// <summary>
/// 上移,移到第一个位置则不动
/// </summary>
public void MoveUp()
{
SuperTreeViewNode tmpNode,tmpParent;
if(this.SelectedNode == null)
return;
//本身已经是第一个节点
if(this.SelectedNode.PrevNode == null)
return;
tmpParent = this.SelectedNode.Parent as SuperTreeViewNode;
tmpNode = this.SelectedNode as SuperTreeViewNode;
string curPath = (this.SelectedNode as SuperTreeViewNode).FullPath;
int curIndex = this.SelectedNode.Index;
//交换两个节点
if(tmpParent == null)//根节点
{
//this.Nodes.Remove(tmpNode);
//删除原有节点,但不删除节点信息
this.DeleteSelectedNodeAndIndex(false);
this.Nodes.Insert(curIndex - 1,tmpNode);
}
else//不是根节点
{
//tmpParent.Nodes.RemoveAt(curIndex);
//删除原有节点,但不删除节点信息
this.DeleteSelectedNodeAndIndex(false);
tmpParent.Nodes.Insert(curIndex - 1,tmpNode);
}
this.SelectedNode = tmpNode;
//激发事件
NodeMoveEventArgs e = new NodeMoveEventArgs();
e.MoveType = NodeMoveType.NodeMoveUp;
e.node = tmpNode;
e.PrevPath = curPath;
this.NodeMove(tmpNode,e);
}
/// <summary>
/// 下移,移到最后一个位置不动
/// </summary>
public void MoveDown()
{
SuperTreeViewNode tmpNode,tmpParent;
if(this.SelectedNode == null)
return;
//本身已经是最后一个节点
if(this.SelectedNode.NextNode == null)
return;
tmpParent = this.SelectedNode.Parent as SuperTreeViewNode;
tmpNode = this.SelectedNode as SuperTreeViewNode;
string curPath = (this.SelectedNode as SuperTreeViewNode).FullPath;
int curIndex = this.SelectedNode.Index;
//交换两个节点
if(tmpParent == null)//根节点
{
//this.Nodes.Remove(tmpNode);
//删除原有节点,但不删除节点信息
this.DeleteSelectedNodeAndIndex(false);
this.Nodes.Insert(curIndex + 1,tmpNode);
}
else//不是根节点
{
//tmpParent.Nodes.RemoveAt(curIndex);
//删除原有节点,但不删除节点信息
this.DeleteSelectedNodeAndIndex(false);
tmpParent.Nodes.Insert(curIndex + 1,tmpNode);
}
this.SelectedNode = tmpNode;
//激发事件
NodeMoveEventArgs e = new NodeMoveEventArgs();
e.MoveType = NodeMoveType.NodeMoveDown;
e.node = tmpNode;
e.PrevPath = curPath;
this.NodeMove(tmpNode,e);
}
/// <summary>
/// 左移,升级,移到顶级节点不动
/// </summary>
public void MoveLeft()
{
if(this.SelectedNode == null)
return;
SuperTreeViewNode tmpParent = this.SelectedNode.Parent as SuperTreeViewNode;
SuperTreeViewNode tmpNode = this.SelectedNode as SuperTreeViewNode;
string curPath = (this.SelectedNode as SuperTreeViewNode).FullPath;
//顶级节点
if(tmpParent == null)
return;
//交换两个节点
if(tmpParent.Parent == null)//顶级节点
{
//删除原有节点,但不删除节点信息
this.DeleteSelectedNodeAndIndex(false);
this.Nodes.Insert(tmpParent.Index,tmpNode);
this.OnNodeMove(tmpNode.FullPath,curPath);
}
else//不是顶级节点
{
//删除原有节点,但不删除节点信息
this.DeleteSelectedNodeAndIndex(false);
tmpParent.Parent.Nodes.Insert(tmpParent.Index + 1,tmpNode);
this.OnNodeMove(tmpNode.FullPath,curPath);
}
this.SelectedNode = tmpNode;
//激发事件
NodeMoveEventArgs e = new NodeMoveEventArgs();
e.MoveType = NodeMoveType.NodeMoveLeft;
e.node = tmpNode;
e.PrevPath = curPath + "\\";
this.NodeMove(tmpNode,e);
}
/// <summary>
/// 右移,降级,无兄弟节点则不动。如有兄弟节点,则成为上一个兄弟节点的子节点。如果本身是所有兄弟节点中的第一个,则成为下一个兄弟的子节点。
/// </summary>
public void MoveRight()
{
if(this.SelectedNode == null)
return;
SuperTreeViewNode tmpNode = this.SelectedNode as SuperTreeViewNode;
string curPath = (this.SelectedNode as SuperTreeViewNode).FullPath;
SuperTreeViewNode tmpBrother;
if(tmpNode.PrevNode == null && tmpNode.NextNode == null)
return;
//有兄弟,且本身不是老大,则降级成为最近一个兄长的最小儿子
if(tmpNode.PrevNode != null)
{
tmpBrother = tmpNode.PrevNode as SuperTreeViewNode;
//删除原选中的节点,但不删除节点信息
this.DeleteSelectedNodeAndIndex(false);
//插入新节点
tmpBrother.Nodes.Add(tmpNode);
//移动后更新节点索引
this.OnNodeMove(tmpNode.FullPath,curPath);
}
//有兄弟,本身是老大,则降级成为老二的最小儿子
if(tmpNode.PrevNode == null && tmpNode.NextNode != null)
{
tmpBrother = tmpNode.NextNode as SuperTreeViewNode;
//删除原选中的节点,但不删除节点信息
this.DeleteSelectedNodeAndIndex(false);
//插入新节点
tmpBrother.Nodes.Add(tmpNode);
//移动后更新节点索引
this.OnNodeMove(tmpNode.FullPath,curPath);
}
this.SelectedNode = tmpNode;
//激发事件
NodeMoveEventArgs e = new NodeMoveEventArgs();
e.MoveType = NodeMoveType.NodeMoveRight;
e.node = tmpNode;
e.PrevPath = curPath + "\\";
this.NodeMove(tmpNode,e);
}
/// <summary>
/// 当节点移动时,处理内部节点索引集合和DataTable
/// </summary>
/// <param name="NewFullPath"></param>
/// <param name="PrevPath"></param>
private void OnNodeMove(string NewFullPath,string PrevPath)
{
DataRow[] drs = this.dtTreeNodes.Select("NodePath Like '" + PrevPath + "%'");
string str,oldPath,newPath;
SuperTreeViewNode node;
foreach(DataRow dr in drs)
{
oldPath = dr["NodePath"].ToString();
str = NewFullPath;
//替换原路径
newPath = str + oldPath.Substring(PrevPath.Length,oldPath.Length - PrevPath.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;
}
}
}
#region 剪切树节点
private SuperTreeViewNode NodeToBeCut = null;
private string NodeToBeCutPath = "";
/// <summary>
/// 剪切节点
/// </summary>
public void CutNode()
{
if(this.SelectedNode == null)
return;
//仅有一个根节点,且被选中
if(this.SelectedNode.Parent == null && this.SelectedNode.NextNode == null && this.SelectedNode.PrevNode == null)
return;
//记录下节点的引用
NodeToBeCut = this.SelectedNode as SuperTreeViewNode;
NodeToBeCutPath = (this.SelectedNode as SuperTreeViewNode).FullPath;
//从树中删除
if(this.SelectedNode.Parent == null)//一级节点
this.Nodes.Remove(NodeToBeCut);
else
this.SelectedNode.Parent.Nodes.Remove(NodeToBeCut);
this.SelectedNode = null;
}
/// <summary>
/// 粘贴节点
/// </summary>
public void PasteNode()
{
if(this.SelectedNode == null)
return;
if(this.NodeToBeCut == null)
return;
//不能粘自己
if(this.SelectedNode == this.NodeToBeCut)
return;
//粘贴
this.SelectedNode.Nodes.Add(this.NodeToBeCut);
//更新索引
this.OnNodeMove(this.NodeToBeCut.FullPath,this.NodeToBeCutPath);
//激发事件
NodeMoveEventArgs e = new NodeMoveEventArgs();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -