using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Xml; using ryCommon; namespace ryControls { /// /// 树形控件,用于分类用 /// public partial class CtlTreeView : TreeView { private NodeItem StringToNodeItem(string tag) { ryCommon.Storage mStor = new ryCommon.Storage(tag); mStor.SelectNodeBySet(); NodeItem item = new NodeItem(mStor.GetAttrValue("keys"), mStor.GetAttrValue("pwd"), mStor.GetAttrValue("user")); return item; } private string NodeItemToString(object Tag) { if (Tag != null) { NodeItem item = (NodeItem)Tag; ryCommon.Storage mStor = new ryCommon.Storage(); mStor.SelectNodeBySet(); mStor.SetAttrValue("keys", item.Keys); mStor.SetAttrValue("pwd", item.Pwd); mStor.SetAttrValue("user", item.AuthUser); return mStor.XMLText; } return ""; } XmlDocument xmlDoc = new XmlDocument();//定义一个XML文档对象 private string m_FirstShowText = "所有数据"; /// /// 显示在第一位的名称 /// [Description("显示在第一位的名称")] public string T_FirstShowText { get { return m_FirstShowText; } set { m_FirstShowText = value; } } private bool m_ShowMenu = true; /// /// 是否显示菜单 /// [Description("是否显示菜单")] public bool T_ShowMenu { get { return m_ShowMenu; } set { m_ShowMenu = value; } } /// /// 树形控件 /// public CtlTreeView() { InitializeComponent(); menuAddGroup.Click += new EventHandler(MenuAddGroup_Click); menuEditGroup.Click += new EventHandler(MenuEditGroup_Click); menuDelGroup.Click += new EventHandler(MenuDelGroup_Click); menuGoPreGroup.Click += new EventHandler(MenuGoPreGroup_Click); menuSetPwd.Click += new EventHandler(MenuSetPwd_Click); menuSetAuthUser.Click += new EventHandler(MenuSetAuthUser_Click); menuGoNextGroup.Click += new EventHandler(MenuGoNextGroup_Click); this.MouseClick += new MouseEventHandler(CtlTreeView_MouseClick); this.ContextMenuStrip = contextMenuStrip1; this.ItemDrag += new ItemDragEventHandler(CtlTreeView_ItemDrag); this.DragEnter += new DragEventHandler(CtlTreeView_DragEnter); this.DragDrop += new DragEventHandler(CtlTreeView_DragDrop); this.DragOver += new DragEventHandler(CtlTreeView_DragOver); this.AfterCheck += new TreeViewEventHandler(CtlTreeView_AfterCheck); this.HotTracking = true; this.HideSelection = false; } void MenuSetAuthUser_Click(object sender, EventArgs e) { TreeNode tn = this.SelectedNode; if (tn == null) { return; } if (tn.Parent == null) { return; } if (OnBeforeSetAuth != null) { bool Cancel = false; OnBeforeSetAuth(this, ref Cancel); if (Cancel) { return; } } TreeXML.FrmAuthUser frm = new TreeXML.FrmAuthUser(); frm.txtAuthUser.Text = GetNodeItem(tn).AuthUser; frm.txtAuthUser.DoubleClick += new EventHandler(TxtAuthUser_DoubleClick); if (frm.ShowDialog(this) == DialogResult.OK) { SetNodeItemForUser(tn, frm.txtAuthUser.Text); OnDataChange?.Invoke(this, new EventArgs()); } } void MenuSetPwd_Click(object sender, EventArgs e) { TreeNode tn = this.SelectedNode; if (tn == null) { return; } if (tn.Parent == null) { return; } if (OnBeforeSetPwd != null) { bool Cancel = false; OnBeforeSetPwd(this, ref Cancel); if (Cancel) { return; } } TreeXML.FrmChangePwd frm = new TreeXML.FrmChangePwd() { oldPwd = GetNodeItem(tn).Pwd }; if (frm.ShowDialog(this) == DialogResult.OK) { SetNodeItem(tn, frm.NewPwd); OnDataChange?.Invoke(this, new EventArgs()); } } private void TreeParentChecked(TreeNode node, bool state) { TreeNode tn = node; while (true) { tn = tn.Parent; if (tn == null) { break; } else { tn.Checked = state; } } } void CtlTreeView_AfterCheck(object sender, TreeViewEventArgs e) { if (this.CheckBoxes) { if (e.Node.Checked && e.Action == TreeViewAction.ByMouse) { //ctlTreeView1.setChildNodeCheckedState(e.Node, true); TreeParentChecked(e.Node, true); this.SetChildNodeCheckedState(e.Node, true); } else if (!e.Node.Checked && e.Action == TreeViewAction.ByMouse) { //ctlTreeView1.setChildNodeCheckedState(e.Node, true); bool isChecked = false; TreeNode tn = e.Node.Parent; if (tn != null) { for (int i = 0; i < tn.Nodes.Count; i++) { if (tn.Nodes[i].Checked) { isChecked = true; break; } } } if (!isChecked) { TreeParentChecked(e.Node, false); } this.SetChildNodeCheckedState(e.Node, false); } } } void CtlTreeView_DragOver(object sender, DragEventArgs e) { } /// /// 判断指定节点是否是目标节点的子节点 /// /// /// /// /// public bool IsChildNode(TreeNode parent, TreeNode child,bool isIncludeMe) { if (parent == child && isIncludeMe) { return true; } TreeNode tn=child.Parent; while (true) { if (tn == parent) { return true; } else { tn = tn.Parent; if (tn == null) { break; } } } return false; } void CtlTreeView_DragDrop(object sender, DragEventArgs e) { //获得拖放中的节点 TreeNode moveNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode"); //根据鼠标坐标确定要移动到的目标节点 Point pt; TreeNode targeNode; pt = ((TreeView)(sender)).PointToClient(new Point(e.X, e.Y)); targeNode = this.GetNodeAt(pt); //如果目标节点无子节点则添加为同级节点,反之添加到下级节点的未端 TreeNode NewMoveNode = (TreeNode)moveNode.Clone(); if (!IsChildNode(moveNode, targeNode, false) && moveNode != targeNode) { //if (targeNode.Nodes.Count == 0) //{ // targeNode.Parent.Nodes.Insert(targeNode.Index, NewMoveNode); //} //else //{ OnBeforeDataChange?.Invoke(this, new EventArgs()); targeNode.Nodes.Insert(targeNode.Nodes.Count, NewMoveNode); //} //移除拖放的节点 moveNode.Remove(); //更新当前拖动的节点选择 this.SelectedNode = NewMoveNode; //展开目标节点,便于显示拖放效果 this.ExpandAll(); OnDataChange?.Invoke(this, new EventArgs()); } } void CtlTreeView_DragEnter(object sender, DragEventArgs e) { if (OnBeforeEditGroup != null) { bool Cancel = false; OnBeforeEditGroup(this, ref Cancel); if (Cancel) { return; } } if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode")) { e.Effect = DragDropEffects.Move; } else { e.Effect = DragDropEffects.None; } } void CtlTreeView_ItemDrag(object sender, ItemDragEventArgs e) { if (e.Button == MouseButtons.Left) { DoDragDrop(e.Item, DragDropEffects.Move); } } void TxtAuthUser_DoubleClick(object sender, EventArgs e) { TextBox ct = (TextBox)sender; string User = ct.Text; bool Cancel=false; OnAuthUserSelect?.Invoke(this,ref User,ref Cancel); if (!Cancel) { ((TextBox)sender).Text = User; } } /// /// 判断当前节点,当前用户是否有权限访问 /// /// /// /// /// public bool IsHaveAuth(TreeNode tn,string user,string pwd) { NodeItem ni = GetNodeItem(tn); if(ni.AuthUser=="" || (";"+ni.AuthUser+";").IndexOf(";"+user+";")>=0) { if(ni.Pwd=="" || ni.Pwd==pwd) { return true; } } return false; } void CtlTreeView_MouseClick(object sender, MouseEventArgs e) { try { TreeView tv = sender as TreeView; TreeNode select = tv.GetNodeAt(e.Location); if (select != null) { //如果选择节点不是null,就设置为你的“选取结点” tv.SelectedNode = select; } } catch{} } /// /// 权限事件 /// /// /// /// public delegate void AuthUserHandler(object sender, ref string User,ref bool Cancel); /// /// 选择权限用户时发生 /// [Description("选择权限用户时发生")] public event AuthUserHandler OnAuthUserSelect; /// /// 数据变化时发生 /// [Description("数据变化时发生")] public event EventHandler OnDataChange; /// /// 数据变化前发生 /// [Description("数据变化前发生")] public event EventHandler OnBeforeDataChange; /// /// 操作事件 /// /// /// public delegate void OptHandler(object sender, ref bool Cancel); /// /// 在添加分组前发生 /// [Description("在添加分组前发生")] public event OptHandler OnBeforeAddGroup; /// /// 在修改分组前发生 /// [Description("在修改分组前发生")] public event OptHandler OnBeforeEditGroup; /// /// 在删除分组前发生 /// [Description("在删除分组前发生")] public event OptHandler OnBeforeDelGroup; /// /// 在设置密码前发生 /// [Description("在设置密码前发生")] public event OptHandler OnBeforeSetPwd; /// /// 在设置权限前发生 /// [Description("在设置权限前发生")] public event OptHandler OnBeforeSetAuth; void MenuGoNextGroup_Click(object sender, EventArgs e) { if (null == this.SelectedNode) { return; } TreeNode node = this.SelectedNode; TreeNode nextNode = node.NextNode; if (null != nextNode) { TreeNode newNode = (TreeNode)node.Clone(); OnBeforeDataChange?.Invoke(this, new EventArgs()); if (null == node.Parent) { this.Nodes.Insert(nextNode.Index + 1, newNode); } else { node.Parent.Nodes.Insert(nextNode.Index + 1, newNode); } node.Remove(); this.SelectedNode = newNode; OnDataChange?.Invoke(this, new EventArgs()); } } void MenuGoPreGroup_Click(object sender, EventArgs e) { if (null == this.SelectedNode) { return; } TreeNode node = this.SelectedNode; TreeNode prevNode = node.PrevNode; if (null != prevNode) { TreeNode newNode = (TreeNode)node.Clone(); OnBeforeDataChange?.Invoke(this, new EventArgs()); if (null == node.Parent) { this.Nodes.Insert(prevNode.Index, newNode); } else { node.Parent.Nodes.Insert(prevNode.Index, newNode); } node.Remove(); this.SelectedNode = newNode; OnDataChange?.Invoke(this, new EventArgs()); } } void MenuDelGroup_Click(object sender, EventArgs e) { if (this.SelectedNode == null) { return; } if (this.SelectedNode.Parent == null) { return; } if (MessageBox.Show("是否真的要删除?一旦删除就不可恢复!\r\n备注:删除分组时,不会删除该分组包含的内容。", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) { return; } if (OnBeforeDelGroup != null) { bool Cancel = false; OnBeforeDelGroup(this, ref Cancel); if (Cancel) { return; } } OnBeforeDataChange?.Invoke(this, new EventArgs()); this.SelectedNode.Remove(); OnDataChange?.Invoke(this, new EventArgs()); } void MenuEditGroup_Click(object sender, EventArgs e) { if (OnBeforeEditGroup != null) { bool Cancel = false; OnBeforeEditGroup(this, ref Cancel); if (Cancel) { return; } } if (this.SelectedNode == null) { return; } if (this.SelectedNode.Parent == null) { return; } TreeXML.frmAddTree frm = new TreeXML.frmAddTree() { T_IsAdd = 0, imageList1 = this.ImageList, T_SelectText = this.SelectedNode.Text, T_SelectTag = GetNodeItem(this.SelectedNode).Keys, T_ImageIndex = this.SelectedNode.ImageIndex }; if (frm.ShowDialog(this) == DialogResult.OK) { OnBeforeDataChange?.Invoke(this, new EventArgs()); this.SelectedNode.Text = frm.T_SelectText; SetNodeItemForKeys(this.SelectedNode, frm.T_SelectTag); this.SelectedNode.ImageIndex = frm.T_ImageIndex; //this.SelectedNode.StateImageIndex = frm.T_ImageIndex; this.SelectedNode.SelectedImageIndex = frm.T_ImageIndex; OnDataChange?.Invoke(this, new EventArgs()); } } void MenuAddGroup_Click(object sender, EventArgs e) { if (OnBeforeAddGroup != null) { bool Cancel = false; OnBeforeAddGroup(this, ref Cancel); if (Cancel) { return; } } if (this.SelectedNode == null) { return; } TreeXML.frmAddTree frm = new TreeXML.frmAddTree() { imageList1 = this.ImageList, T_IsAdd = 1 }; if (frm.ShowDialog(this) == DialogResult.OK) { OnBeforeDataChange?.Invoke(this, new EventArgs()); TreeNode new_child = new TreeNode() { Text = frm.T_SelectText }; SetNodeItemForKeys(new_child, GetNewKey()); new_child.ImageIndex = frm.T_ImageIndex; new_child.SelectedImageIndex = frm.T_ImageIndex; //new_child.StateImageIndex = frm.T_ImageIndex; this.SelectedNode.Nodes.Add(new_child); this.ExpandAll(); OnDataChange?.Invoke(this, new EventArgs()); } } /// /// 获取新的关键词分类 /// /// private string GetNewKey() { Dictionary dict = new Dictionary(); DiGui(Nodes[0]); int i = 0; while(true) { if(!dict.ContainsKey("N"+i.ToString())) { return "N" + i.ToString(); } i++; } void DiGui(TreeNode tn) { // foreach (TreeNode tnSub in tn.Nodes) { NodeItem item = GetNodeItem(tnSub); if(!dict.ContainsKey(item.Keys)) { dict.Add(item.Keys, 1); } DiGui(tnSub); } } } /// /// 根据id获取节点 /// /// /// public XmlElement GetNodeInfoById(string id) { //根据指定路径获取节点 XmlElement element = null; XmlNode xmlNode = xmlDoc.SelectSingleNode("root/list[@id='" + id + "']"); element = (XmlElement)xmlNode; return element; } /// /// 根据节点获取节点信息 /// /// /// public NodeItem GetNodeItem(TreeNode tn) { if (tn.Tag != null && tn.Tag.ToString() != "") { return (NodeItem)tn.Tag; } else { tn.Tag= new NodeItem("", "", ""); return (NodeItem)tn.Tag; } } /// /// 设置节点信息 /// /// /// public void SetNodeItem(TreeNode tn,NodeItem ni) { NodeItem item = GetNodeItem(tn); OnBeforeDataChange?.Invoke(this, new EventArgs()); item = ni; } /// /// 设置节点关键词和密码 /// /// /// /// public void SetNodeItem(TreeNode tn,string Keys,string pwd) { NodeItem item = GetNodeItem(tn); OnBeforeDataChange?.Invoke(this, new EventArgs()); item.Keys = Keys; item.Pwd = pwd; } /// /// 设置节点密码 /// /// /// public void SetNodeItem(TreeNode tn,string pwd) { NodeItem item = GetNodeItem(tn); OnBeforeDataChange?.Invoke(this, new EventArgs()); item.Pwd = pwd; } /// /// 设置节点关键词 /// /// /// public void SetNodeItemForKeys(TreeNode tn, string Keys) { NodeItem item = GetNodeItem(tn); OnBeforeDataChange?.Invoke(this, new EventArgs()); item.Keys = Keys; } /// /// 设置节点用户 /// /// /// public void SetNodeItemForUser(TreeNode tn, string User) { NodeItem item = GetNodeItem(tn); OnBeforeDataChange?.Invoke(this, new EventArgs()); item.AuthUser = User; } /// /// RecursionTreeControl:表示将XML文件的内容显示在TreeView控件中 /// /// 将要加载的XML文件中的节点元素 /// 将要加载的XML文件中的节点集合 private void RecursionTreeControl(XmlNode xmlNode, TreeNodeCollection nodes) { foreach (XmlNode node in xmlNode.ChildNodes)//循环遍历当前元素的子元素集合 { TreeNode new_child = new TreeNode(); try { new_child.Text = (node.Attributes["Value"].Value == "null" ? "" : node.Attributes["Value"].Value) ; try { var ImageIndex= node.Attributes["ImageIndex"].Value.ToInt(); var ImageKey = node.Attributes["ImageKey"]; var ImageKey_Str = ImageKey==null?"": ImageKey.Value; if (ImageKey_Str == "") { new_child.ImageIndex = ImageIndex; new_child.SelectedImageIndex = new_child.ImageIndex; } else { if (ImageList != null && ImageList.Images.Keys.Contains(ImageKey_Str)) { new_child.ImageKey = ImageKey_Str; new_child.SelectedImageKey = new_child.ImageKey; } else { new_child.ImageIndex = ImageIndex; new_child.SelectedImageIndex = new_child.ImageIndex; } } //new_child.StateImageIndex = new_child.ImageIndex; } catch { } // NodeItem item = StringToNodeItem(node.Attributes["Tag"].Value); new_child.Tag = item; } catch { new_child.Tag = null; } switch (node.HasChildNodes)//判断是否存在子节点如果有继续递归 { case true: RecursionTreeControl(node, new_child.Nodes); break; case false: break; } nodes.Add(new_child);//写入 } } /// /// 把XML文本载入到列表中 /// /// public void LoadFromXMLText(string XMLText) { try { base.Nodes.Clear(); xmlDoc.RemoveAll(); xmlDoc.LoadXml(XMLText);//加载XML文件 TreeNode node = base.Nodes.Add(m_FirstShowText); node.Tag = null; RecursionTreeControl(xmlDoc.DocumentElement, node.Nodes);//在TreeView控件中显示内容 base.ExpandAll();//展开TreeView控件中的所有项 } catch { xmlDoc.LoadXml("");//加载XML文件 base.Nodes.Add(m_FirstShowText).Tag=""; } if(base.Nodes.Count>0) { SelectedNode = base.Nodes[0]; } } /// /// 把XML文件载入到列表中 /// /// public void LoadFromFile(string Path) { base.Nodes.Clear(); xmlDoc.Load(Path);//加载XML文件 RecursionTreeControl(xmlDoc.DocumentElement, base.Nodes.Add(m_FirstShowText).Nodes);//在TreeView控件中显示内容 base.ExpandAll();//展开TreeView控件中的所有项 } private void TransTreeSav(TreeNodeCollection nodes, XmlElement ParXmlnode) { XmlNode Xmlroot; XmlElement xmlnode; Xmlroot = xmlDoc.SelectSingleNode("root"); foreach (TreeNode node in nodes) { xmlnode = xmlDoc.CreateElement("list"); xmlnode.SetAttribute("Value", node.Text); xmlnode.SetAttribute("Tag", NodeItemToString(node.Tag)); xmlnode.SetAttribute("ImageIndex", node.ImageIndex.ToString()); xmlnode.SetAttribute("ImageKey", node.ImageKey); ParXmlnode.AppendChild(xmlnode); if (node.Nodes.Count > 0) { TransTreeSav(node.Nodes, xmlnode); } } } /// /// 将列表保存为xml文本 /// /// public string SaveToXmlText() { xmlDoc = new XmlDocument(); //-------遍历树的各个故障节点,同时添加节点至XML xmlDoc.LoadXml(""); XmlElement Xmlnode = xmlDoc.CreateElement("list"); XmlNode Xmlroot = xmlDoc.SelectSingleNode("root"); //------遍历原treeview控件,并生成相应的XML TransTreeSav(base.Nodes[0].Nodes, (XmlElement)Xmlroot); return xmlDoc.OuterXml; } /// /// 改变所有子节点的状态 /// /// /// public void SetChildNodeCheckedState(TreeNode currNode, bool state) { TreeNodeCollection nodes = currNode.Nodes; if (nodes.Count > 0) foreach (TreeNode tn in nodes) { tn.Checked = state; SetChildNodeCheckedState(tn, state); } } /// /// 反选子节点 /// /// public void SetChildNodeInvertChecked(TreeNode currNode) { TreeNodeCollection nodes = currNode.Nodes; if (nodes.Count > 0) foreach (TreeNode tn in nodes) { tn.Checked =!tn.Checked; SetChildNodeInvertChecked(tn); } } private void SetKeyCheckedState(TreeNode currNode, bool state, string keys) { TreeNodeCollection nodes = currNode.Nodes; if (nodes.Count > 0) foreach (TreeNode tn in nodes) { if (keys.IndexOf(FormatKeysInfo(GetNodeItem(tn).Keys)) >= 0) { tn.Checked = state; } SetKeyCheckedState(tn, state, keys); } } /// /// 根据关键词来选中列表 /// /// public void CheckedTreeByKey(string sKey) { for (int i = 0; i < Nodes.Count; i++) { SetKeyCheckedState(Nodes[i], true, sKey); } } /// /// 根据关键词来选中列表 /// /// public void SelectedTreeByKey(string sKey) { for (int i = 0; i < Nodes.Count; i++) { SetKeySelected(Nodes[i], true, sKey); } } private void SetKeySelected(TreeNode currNode, bool state, string keys) { TreeNodeCollection nodes = currNode.Nodes; if (nodes.Count > 0) foreach (TreeNode tn in nodes) { if (keys==FormatKeysInfo(GetNodeItem(tn).Keys)) { this.SelectedNode = tn; break; } SetKeySelected(tn, state, keys); } } /// /// 格式化关键字(会去除重复项),以便存入数据库 /// /// /// public string FormatKeysInfo(string KeyItems) { string tmpKeyItems = GetNoSame(KeyItems); tmpKeyItems = tmpKeyItems.Replace(";;", ";"); tmpKeyItems = tmpKeyItems.Replace(";", ";"); if (tmpKeyItems == ";" || tmpKeyItems.Length < 1) { tmpKeyItems = ""; return tmpKeyItems; } tmpKeyItems = ";" + tmpKeyItems.Trim(';') + ";"; return tmpKeyItems; } /// /// 去除掉重复项 /// /// /// public string GetNoSame(string sList) { string[] item = sList.Split(";".ToCharArray()); string tmpStr = ""; for (int i = 0; i < item.Length; i++) { if (item[i] != "" && (";" + tmpStr + ";").IndexOf(item[i]) < 0) { tmpStr += ";" + item[i]; } } return tmpStr; } /// /// 获取当前选中项以及所有父项的关键词组合 /// /// public string GetKey() { if (SelectedNode == null) { return ""; } if (SelectedNode.Parent != null) { TreeNode item = SelectedNode; string sKeys = ""; while (item.Parent != null) { sKeys += ";" + GetNodeItem(item).Keys; item = item.Parent; } return FormatKeysInfo(GetNoSame(sKeys)); } return ""; } /// /// 获取选中的 /// /// /// /// public string GetCheckedKey(string key_text,TreeViewEventArgs e) { if (e.Node.Checked) { string sKeys = key_text + ";" + GetNodeItem(e.Node).Keys; return FormatKeysInfo(sKeys); } else { string sKeys = ";" + key_text + ";"; sKeys = FormatKeysInfo(sKeys); string myKey = GetNodeItem(e.Node).Keys; if (myKey != "") { sKeys = sKeys.Replace(myKey, ""); } return FormatKeysInfo(sKeys); } } private void ContextMenuStrip1_Opening(object sender, CancelEventArgs e) { if (!m_ShowMenu) { e.Cancel = true; } if (this.SelectedNode == null) { return; } menuAddGroup.Enabled=this.SelectedNode.Name != "nokeys"; if (this.SelectedNode.Parent == null) { menuDelGroup.Enabled = false; menuEditGroup.Enabled = false; menuGoNextGroup.Enabled = false; menuGoPreGroup.Enabled = false; } else { menuDelGroup.Enabled = true; menuEditGroup.Enabled = true; menuGoNextGroup.Enabled = true; menuGoPreGroup.Enabled = true; } } } }