/*****************************************************************************

创建时间       :2019年11月19日

文件名         :Tree_.cs

功能           :树型数据结构
  
作者           :李锋

微信号         :lifengwx2005

Email          :ruizhilf@139.com
  
联系电话       :1382877886

----------------------最后一次修改时间:2022年08月30日
 
*******************************************************************************/

#if _WINDOWS_DESKTOP_

using System;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace lf
{

/// <summary>
    /// 一般树(N叉树)结点。
    /// </summary>
    public class TreeNode_
    {    
        /// <summary>
        /// 数据
        /// </summary>
        public string Data { set; get; }

/// <summary>
        /// 第一个子结点
        /// </summary>
        public TreeNode_ FirstChild { set; get; }

/// <summary>
        /// 下一个兄弟结点
        /// </summary>
        public TreeNode_ NextSibling { set; get; }

public TreeNode_()
        {
            FirstChild = null;
            NextSibling = null;
        }

public TreeNode_(TreeNode_ tn)
        {
            Data = tn.Data;
            FirstChild = tn.FirstChild;
            NextSibling = tn.NextSibling;
        }

/// <summary>
        /// 判断 tnChild 是否 tnParent 的直系子结点,如果是,则返回 true
        /// </summary>
        /// <param name="tnChild"></param>
        /// <returns></returns>
        /// 创建时间:2022-07-18 最后一次修改时间:2022-07-18
        public bool IsMyChild(TreeNode_ tnChild)
        {
            if(tnChild == null) return false;

TreeNode_ tnTemp = FirstChild;

while (tnTemp != null)
            {
                if (tnTemp == tnChild)
                    return true;

tnTemp = tnTemp.NextSibling;
            }

return false;
        }

/// <summary>
        /// 判断 tnChild 是否父结点,如果是,则返回 true
        /// </summary>
        /// <param name="tnParent">父结点</param>
        /// <returns></returns>
        /// 创建时间:2022-07-18 最后一次修改时间:2022-07-18
        public bool IsMyParent(TreeNode_ tnParent)
        {
            if (tnParent == null) return false;

TreeNode_ tnTemp = tnParent.FirstChild;

while (tnTemp != null)
            {
                if (tnTemp == this)
                    return true;

tnTemp = tnTemp.NextSibling;
            }

return false;
        }

};

public class Tree_
    {
        public TreeNode_ First { get;  set; }

public TreeNode_ GetLastSibling(TreeNode_ tnFirstSibling)
        {
            TreeNode_ tnTemp = tnFirstSibling.NextSibling;

if (tnTemp == null)
            {
                return tnFirstSibling;
            }
            else
            {
                TreeNode_ tnLastSibling = null;

while (true)
                {
                    tnLastSibling = tnTemp;
                    tnTemp = tnTemp.NextSibling;

if (tnTemp == null)
                    {
                        return tnLastSibling;                        
                    }
                }
            }
        }

public virtual bool RemoveNote(TreeNode_ tnRemove)
        {
            if (First == tnRemove)
            {
                First = First.NextSibling;
                return true;
            }

TreeNode_ tnParent = FindIsFirstChild(First, tnRemove);
            if (tnParent == null)
            {
                TreeNode_ tnPrevSibling = FindPrevSibling(First, tnRemove);
                if (tnPrevSibling == null)
                {
                    return false;
                }
                else
                {
                    tnPrevSibling.NextSibling = null;
                    return true;
                }
            }
            else
            {
                lg.ShowInfo("tnParent!=null");

tnParent.FirstChild = null;

return true;
            }
        }

/// <summary>
        /// 判断tnFind是否tnFindStart或者tnFindStart下面任何一个节点的第一个子节点,如果不是返回NULL,否刚返回它的父节点
        /// </summary>
        /// <param name="tnFindStart">查找开始位置</param>
        /// <param name="tnFind">所查找的节点</param>
        /// <returns>找到则返回父节点,否则返回NULL</returns>
        public TreeNode_ FindIsFirstChild(TreeNode_ tnFindStart, TreeNode_ tnFind)
        {
            if (tnFindStart == tnFind || tnFindStart == null)
                return null;

TreeNode_ tn = tnFindStart;
            while (tn != null)
            {
                if (tn.FirstChild == tnFind)
                    return tn;
                else
                {
                    TreeNode_ tmp = FindIsFirstChild(tn.FirstChild, tnFind);
                    if (tmp != null)
                        return tmp;
                }       
                tn = tn.NextSibling;
            }
            return null;
        }

/// <summary>
        /// 从tnStart处遍历二叉树,查找 tnNode的上一个兄弟节点
        /// </summary>
        /// <param name="tnStart">查找开始处</param>
        /// <param name="tnNode">要查找的节点</param>
        /// <returns>找到则返回上一个兄弟节点,否则返回NULL</returns>
        /// 创建时间:????-??-?? 最后一次修改时间:2022-07-18
        public TreeNode_ FindPrevSibling(TreeNode_ tnStart, TreeNode_ tnNode)
        {
            if (tnStart == tnNode || tnStart == null)
                return null;

TreeNode_ tn = tnStart;
            while (tn != null)
            {
                if (tn.NextSibling == tnNode)
                    return tn;
                else
                {
                    if (tn.FirstChild != null)
                    {
                        TreeNode_ tmp = FindPrevSibling(tn.FirstChild, tnNode);
                        if (tmp != null)
                            return tmp;
                    }
                }

tn = tn.NextSibling;
            }

return null;
        }

/// <summary>
        /// 遍历所有节点,查找它的子结点,如果子结点包含 tnChild,则返回此结点.
        /// </summary>
        /// <param name="tnChild">子结点</param>
        /// <returns></returns>
        /// 创建时间:2022-07-18 最后一次修改时间:2022-07-18
        public TreeNode_ FindPrent(TreeNode_ tnStart, TreeNode_ tnChild)
        {

TreeNode_ tnTemp = tnStart;

while(tnTemp != null)
            {
                //lg.D("tnTemp = " + ((TreeViewTreeNode_)tnTemp).DispalyText, "public TreeNode_ FindPrent");

if (tnTemp.IsMyChild(tnChild))
                    return tnTemp;

TreeNode_ tnResult = FindPrent(tnTemp.FirstChild, tnChild);

if(tnResult != null)
                {
             
                    return tnResult;
                }

tnTemp = tnTemp.NextSibling;
            }
      
           
            return null; 
        }

}

public class TreeViewTreeNode_ : TreeNode_
    {

public const string m_Split = "||||";

/// <summary>
        /// 键值,TreeView 的TreeNode的name,是唯一的
        /// </summary>
        public Int64 KeyValue { get; set; }                      
        
        /// <summary>
        /// 子节点的键值,-1 为没有。 
        /// </summary>
        public Int64 FirstChildKeyValue { get; set; }

/// <summary>
        /// 父节点的键值,如果为空,则为根节点
        /// </summary>
        public Int64 NextSiblingKeyValue { get; set; }

/// <summary>
        /// 分隔字符串
        /// </summary>
        public string SplitString { get { return m_Split; } }

/// <summary>
        /// 在TreeView显示的文本
        /// </summary>
        public string DispalyText { get; set; }

/// <summary>
        /// 在TreeView显示文本的字体颜色
        /// </summary>
        public Color DisplayForeColor { get; set; }

/// <summary>
        /// 在TreeView显示文本的背景颜色
        /// </summary>
        public Color DisplayBackColor { get; set; }

/// <summary>
        /// 在TreeView显示的字体
        /// </summary>
        public Font DispalyFont { get; set; }

public TreeViewTreeNode_(string sDispalyText = "")
        {
            KeyValue = GetNewKeyname();
            FirstChildKeyValue = -1;
            NextSiblingKeyValue = -1; 
            DispalyText = sDispalyText;
            DisplayForeColor = Color.Black;
            DisplayForeColor = Color.White;
            DispalyFont = new Font("微软雅黑", 12);   
        }

public Int64 GetNewKeyname()
        {
            Int64 _t;
            sdk.QueryPerformanceCounter(out _t);

return _t;
        }

/// <summary>
        /// 打包数据
        /// </summary>
        public string PackageData()
        {
            Data = Data + GetPackageDataAdd();

return Data;
        }

public string GetPackageDataAdd()
        {
            //Data |||| KeyValue |||| FirstChildKeyValue |||| NextSiblingKeyValue ||||  DispalyText |||| DisplayForeColor |||| DisplayBackColor |||| DispalyFont + ||||  Length

// Length  = |||| KeyValue |||| FirstChildKeyValue |||| NextSiblingKeyValue ||||  DispalyText |||| DisplayForeColor |||| DisplayBackColor |||| DispalyFont + ||||

if (KeyValue == -1 || DispalyText == null ||  DispalyText == "" || DispalyFont == null )
                throw new Exception(@"KeyValue == -1 || DispalyText == null ||  DispalyText == "" || DispalyFont == null");
            
            
            string sAdd = m_Split + KeyValue.ToString() + m_Split + FirstChildKeyValue.ToString() + m_Split + NextSiblingKeyValue.ToString() + m_Split + DispalyText + m_Split;

System.Drawing.ColorConverter cc = new System.Drawing.ColorConverter();
            string tmp = cc.ConvertToString(DisplayForeColor);
            sAdd = sAdd + tmp + m_Split;

tmp = cc.ConvertToString(DisplayBackColor);
            sAdd = sAdd + tmp + m_Split;

System.Drawing.FontConverter fc = new System.Drawing.FontConverter();
            tmp = fc.ConvertToString(DispalyFont);
            sAdd += tmp;

sAdd += m_Split;

sAdd += sAdd.Length.ToString();
            
            return sAdd;
        }

/// <summary>
        /// 在磁盘中读取数据后,还要运行这个函数
        /// </summary>
        public void SplitData()
        {
            //Data |||| KeyValue |||| FirstChildKeyValue |||| FirstChilNextSiblingKeyValue ||||  DispalyText |||| DisplayForeColor |||| DisplayBackColor |||| DispalyFont + |||| +  Length

// Length  = |||| KeyName |||| FirstChildKeyValue |||| NextSiblingKeyValue ||||  DispalyText |||| DisplayForeColor |||| DisplayBackColor |||| DispalyFont + ||||

string NewData = "";

int nLengthStart = Data.LastIndexOf(m_Split, Data.Length);

if (nLengthStart == -1)
                throw new Exception("nLengthStart = -1");

string sLength = Data.Substring(nLengthStart + m_Split.Length, Data.Length - nLengthStart - m_Split.Length);
         
            if (!sLength._IsNumberString())
                throw new Exception("!sLength.isNumberString()");

int nAttribute = System.Convert.ToInt32(sLength);

NewData = Data.Substring(0, Data.Length - nAttribute - sLength.Length);

string sAttribute = Data.Substring(NewData.Length + m_Split.Length, nAttribute - m_Split.Length - m_Split.Length);

StringList_ ls = sAttribute._Split(m_Split);

if (ls.Count != 7)
                throw new Exception("sAttribute = " + sAttribute + "分隔sAttribute错误, ls.Count != 7");

KeyValue = System.Convert.ToInt64(ls[0]);

FirstChildKeyValue = System.Convert.ToInt64(ls[1]);

NextSiblingKeyValue = System.Convert.ToInt64(ls[2]);

DispalyText = ls[3];

System.Drawing.ColorConverter cc = new System.Drawing.ColorConverter();
            DisplayForeColor = (System.Drawing.Color)cc.ConvertFromString(ls[4]);
            DisplayBackColor = (System.Drawing.Color)cc.ConvertFromString(ls[5]);

System.Drawing.FontConverter fc = new System.Drawing.FontConverter();
            DispalyFont = fc.ConvertFromString(ls[6]) as System.Drawing.Font;
            
            Data = NewData;
        }

};

/// <summary>
    /// 树型数据显示
    /// </summary>
    public class TreeDataView_ : Tree_
    {
        //固定名子,原来用控件名子,但是一旦控件名字更改,就是个bug,文件打不开了。
        private const string ConstName = "TreeView";  

        
        private TreeView m_TreeView;

/// <summary>
        /// 树型控件是否改变
        /// </summary>
        public bool IsModify { set; get;}

/// <summary>
        /// 文件件
        /// </summary>
        public string KeyBinaryFullPathName  { get; set;}

/// <summary>
        /// 显示的TreeView控件
        /// </summary>
        public TreeView DisplayTreeView { get { return m_TreeView; } set { m_TreeView = value; } }

public string Name { get; private set; }

public void AddChild(TreeViewTreeNode_ tnParent, TreeViewTreeNode_ tnChild)
        {
            if (tnParent == null || tnChild == null)
            {
                throw new Exception("tnParent == null || tnChild == null");
            }

TreeViewTreeNode_ tnTemp = (TreeViewTreeNode_)tnParent.FirstChild;

if (tnTemp == null)
            {
                tnParent.FirstChild = tnChild;
                tnParent.FirstChildKeyValue = tnChild.KeyValue;
            }
            else
            {
                AddSibling(tnTemp, tnChild);

}

IsModify = true;
        }

/// <summary>
        /// 
        /// </summary>
        /// <param name="tnRemove"></param>
        /// <returns></returns>
        /// 创建时间: ????-??-??      最后一次修改时间:2022-05-30
        public override bool RemoveNote(TreeNode_ tnRemove)
        {
            if (First == tnRemove)
            {              
                First = First.NextSibling;
                return true;
            }

TreeViewTreeNode_ tnParent = (TreeViewTreeNode_)FindIsFirstChild(First, tnRemove);
            if(tnParent == null)
            {
                TreeViewTreeNode_ tnPrevSibling = (TreeViewTreeNode_)FindPrevSibling(First, tnRemove);//上一个兄弟节点
                if(tnPrevSibling == null) 
                {
                    return false;
                }
                else //上一个兄弟结点连结下一个兄弟结点
                {
                    tnPrevSibling.NextSibling = tnRemove.NextSibling;
                    tnPrevSibling.NextSiblingKeyValue = (tnRemove as TreeViewTreeNode_).NextSiblingKeyValue;
                    return true;
                }
                 
            }
            else
            {

tnParent.FirstChild = null;
                tnParent.FirstChildKeyValue = -1;
                
                return true;
            }
        }

/// <summary>
        /// 添加兄弟节点
        /// </summary>
        /// <param name="tnFirstSibling">第一个兄弟</param>
        /// <param name="tnNewSibling">新的兄弟节点</param>
        public void AddSibling(TreeViewTreeNode_ tnFirstSibling, TreeViewTreeNode_ tnNewSibling)
        {
            if (tnNewSibling == null)
            {
                throw new Exception("给定的新兄弟节点不能为空!");
            }

if (tnFirstSibling == null)
            {
                if (First != null)
                {
                    throw new Exception("给定的第一个兄弟节点不能为空!");
                }
                else
                {
                    First = tnNewSibling;
                }
            }
            else
            {
                TreeViewTreeNode_ tnLastSibling = (TreeViewTreeNode_)GetLastSibling(tnFirstSibling);

tnLastSibling.NextSibling = tnNewSibling;
                tnLastSibling.NextSiblingKeyValue = tnNewSibling.KeyValue;
            }

}

/// <summary>
        /// 在结点 tnFindStart 中的子结点中查找节点键值为 iKeyValue 的结点,包括结点 tnFindStart
        /// </summary>
        /// <param name="tnFindStart">开始查找的结点</param>
        /// <param name="sKeyValue">键值</param>
        /// <returns>返回第一次出现的结点</returns>
        /// <exception cref="Exception"></exception>
        /// 创建时间:????-??-?? 最后一次修改时间:2022-07-18
        public TreeViewTreeNode_ Find(TreeViewTreeNode_ tnFindStart, string sKeyValue)
        {            
            try
            {
                if (!sKeyValue._IsNumberString())
                {
                    lg.D("错误: sKeyValue=“" + sKeyValue + "” 不是数字!", "TreeDataView_.Find");
                    return null;
                }                
                return Find(tnFindStart, System.Convert.ToInt64(sKeyValue));                
            }
            catch (Exception e)
            {
                lg.ShowError(e.Message, "TreeDataView_.Find");
                lg.D(e.Message, "TreeDataView_.Find");
            }

return null;
        }

/// <summary>
        /// 在结点 tnFindStart 中的子结点中查找节点键值为 iKeyValue 的结点,包括结点 tnFindStart
        /// </summary>
        /// <param name="tnFindStart">开始查找的结点</param>
        /// <param name="iKeyValue">键值</param>
        /// <returns>返回第一次出现的结点</returns>
        /// <exception cref="Exception"></exception>
        /// 创建时间:????-??-?? 最后一次修改时间:2022-07-18
        public TreeViewTreeNode_ Find(TreeViewTreeNode_ tnFindStart, Int64 iKeyValue)
        {
           
            if (tnFindStart == null ||  iKeyValue == -1 )                 
                throw new Exception("tnFindStart == null ||  iKeyValue == -1");
            
            if (First == null)      return null;

TreeViewTreeNode_ tnTmp = tnFindStart;

while (tnTmp != null)
            {
                if (tnTmp.KeyValue == iKeyValue)  //查找节点本身
                {
                    return tnTmp;
                }
                else
                { 
                    //查找节点的子节点
                    if(tnTmp.FirstChild != null)
                    { 
                        TreeViewTreeNode_ tnFind = Find((TreeViewTreeNode_)tnTmp.FirstChild, iKeyValue);
                        if(tnFind != null)
                        {
                            return tnFind;
                        }
                    }
                }

//如果都还没找到,继续查找兄弟节点
                tnTmp = (TreeViewTreeNode_)tnTmp.NextSibling;
            }

return null;
        }

public TreeViewTreeNode_ FindDispalyText(TreeViewTreeNode_ tnFindStart, string sDispalyText)
        {
            if (tnFindStart == null || sDispalyText == "")
                throw new Exception("tnFindStart == null ||  sDispalyText == \"\"");

if (First == null) return null;

TreeViewTreeNode_ tnTmp = tnFindStart;

while (tnTmp != null)
            {
                if (tnTmp.DispalyText == sDispalyText)  //查找节点本身
                {
                    return tnTmp;
                }
                else
                {
                    //查找节点的子节点
                    if (tnTmp.FirstChild != null)
                    {
                        TreeViewTreeNode_ tnFind = FindDispalyText((TreeViewTreeNode_)tnTmp.FirstChild, sDispalyText);
                        if (tnFind != null)
                        {
                            return tnFind;
                        }
                    }
                }

//如果都还没找到,继续查找兄弟节点
                tnTmp = (TreeViewTreeNode_)tnTmp.NextSibling;
            }

return null;
        }
        
        public TreeViewTreeNode_ GetFirst()
        {
            return (TreeViewTreeNode_)First;
        }

/*
        /// <summary>
        /// 在父节点KeyName=sParentNoteKeyName所有子节后面再添加一个节点。
        /// </summary>
        /// <param name="sText"></param>
        /// <param name="sFont"></param>
        /// <param name="sData"></param>
        /// <param name="sParentNoteKeyName"></param>
        /// <returns></returns>
        public void Add(string sParentNoteKeyName, string sDisplayText, Color cDisplayBackColor, 
            Color cDisplayForeColor, Font fDisplayFont = null, string sData = "")
        {
            TreeViewTreeNode_ tnParent = null;

if (sParentNoteKeyName.Trim().Length != 0)
            {
                tnParent = Find(null,sParentNoteKeyName);
                
                if(tnParent == null)
                {
                    string sError = "查找KeyName = " + sParentNoteKeyName + "的节点不存在!";
                    lg.d(sError, "TreeDataView_.Add");
                    throw new Exception(sError);
                }
            }

TreeViewTreeNode_ tnNew = new TreeViewTreeNode_();

if (fDisplayFont == null)
                tnNew.DispalyFont = m_TreeView.Font;
            else
                tnNew.DispalyFont = fDisplayFont;

tnNew.DispalyText = sDisplayText;

tnNew.DisplayBackColor = cDisplayBackColor;
            tnNew.DisplayForeColor = cDisplayForeColor;
                         
            
            tnNew.FirstChild = null;
            tnNew.NextSibling = null;

if (tnParent != null) //添加子节点
            {       
                tnNew.ParentKeyName = tnParent.KeyName;
                AddChild(tnParent, tnNew);
            }
            else //添加根节点
            {
                tnNew.ParentKeyName = "";
                AddSibling(First, tnNew);

}
            ++Count;             
        }

*/

public void Add(TreeViewTreeNode_ tvtParent,TreeViewTreeNode_ tvtNew)
        {
            if (tvtNew == null)
                throw new Exception("tvtNew == null");

if(tvtParent == null)
            {
                if(First == null)
                {
                    First = tvtNew;   
                }
                else
                {
                    this.AddSibling((TreeViewTreeNode_)First, tvtNew);
                }
            }
            else
            {
                AddChild(tvtParent, tvtNew);
            }
        }

/// <summary>
        /// 在LDlist列表中查找键值为 iKeyValue 的结点
        /// </summary>
        /// <param name="tnList"></param>
        /// <param name="iFirstChildKeyValue"></param>
        /// <returns></returns>
        /// 创建时间:????-??-?? 最后一次修改时间:2022-07-18
        private TreeViewTreeNode_ Find(DList_<TreeViewTreeNode_> tnList, Int64 iKeyValue)
        {        
            DListNote_<TreeViewTreeNode_> tn = tnList.First;
            while (tn != null)
            {
                if (tn.Data.KeyValue == iKeyValue)
                    return tn.Data;
                tn = tn.Next;
            }
            return null;
        }

/// <summary>
        /// 从文件中建立树,返回上次TTreeNote最后一次所选节点Name       
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        /// 创建时间:????-??-?? 最后一次修改时间:2022-07-30
        public string BuildInFile()
        {
            Clear();  //清除数据

KeyBinaryFile_ kbf = new KeyBinaryFile_(KeyBinaryFullPathName);
            kbf.OpenFile();

//StringList_ ls = kbf.getIncludeKeyList(tvName + TreeViewTreeNode_.m_Split);
            //这里有一个 bug ,旧的 TreeView 建立的,在新的TreeView显示不了,因为这跟名子相关,TreeView控件名子变了,为了不改动大量的代码
            //每次文件保存时,写入TreeView控件的名子 
            //String tvName = kbf.getString("Last_TreeView_Name", "");

/*
            String tvName = kbf.getString("Last_TreeView_Name", "");

if (tvName == "") //旧的文件是显示不了的,但是用新版本程序保存一下时,就可以显示出来了。
            {
                tvName = m_TreeView.Name;
                lg.ShowError("无法读取最后写入文件时TreeView控件的名子,将启用新的默认TreeView控件名称。", "BuildInFile");
            }         
            */

StringList_ ls = kbf.getIncludeKeyList(ConstName + TreeViewTreeNode_.m_Split);

//以前版本的 constName 都是 TreeView 控件的名子,一旦控件名子改了,就建立不了数据了。
            //-------------------------------------------------------------------------------------版本兼容
            String oldConstName = "";
            if (ls.Count == 0)  
            {
                ls = kbf.getIncludeKeyList(TreeViewTreeNode_.m_Split);
                
                if(ls.Count > 0)
                {
                    oldConstName = ls[0]._Split(TreeViewTreeNode_.m_Split)[0];
                }

                lg.ShowInfo("旧版本文件!");
            }
            else
            {
                oldConstName = ConstName;
            }

            //------------------------------------------------------------------------------------------------

if (ls.Count == 0) return "-1";

DList_<TreeViewTreeNode_> tnList = new DList_<TreeViewTreeNode_>();
            for (int i = 0; i < ls.Count; ++i)
            {

string sData = kbf.getStringNotNull(ls[i]);
                TreeViewTreeNode_ tvtn = new TreeViewTreeNode_();
                tvtn.Data = sData;
                tvtn.SplitData();
                tnList.Add(tvtn);
            }

//--------------------------------------建立树

//建立First节点
            string sFirstKeyValue = kbf.getString(oldConstName + "_First");
            string sSelectName    = kbf.getString(oldConstName + "_Select");

kbf.ClearAll();
            kbf = null;

int n = ls.IndexOf(oldConstName + TreeViewTreeNode_.m_Split + sFirstKeyValue);

if (n != -1) 
            {   
                First = tnList[n];

}
            else
            {

return "不能建立First节点!";

//throw new Exception("不能建立First节点!");
            }

//建立关系
            DListNote_<TreeViewTreeNode_> dn = tnList.First;

while(dn != null)            
            {
                TreeViewTreeNode_ tvtn = dn.Data;
                TreeViewTreeNode_ tn = null;

if (tvtn.FirstChildKeyValue != -1)
                {
                    tn = Find(tnList, tvtn.FirstChildKeyValue);
                    if (tn == null)
                        throw new Exception("无法找到FirstChild!");
                    else
                        tvtn.FirstChild = tn;
                }

if(tvtn.NextSiblingKeyValue != -1)
                {
                    tn = Find(tnList, tvtn.NextSiblingKeyValue);
                    if (tn == null)
                        throw new Exception("无法找到NextSibling!");
                    else
                        tvtn.NextSibling = tn;
                }

dn = dn.Next;
            }

return sSelectName;
        }

/// <summary>
        /// 把树显示在树型控件上
        /// </summary>
        /// <param name="tnParent">树型控年的父节点,如果父节点为空,则直接建立根节点</param>
        /// <param name="tvtnNote">节点开始处</param>
        private void BuildTreeView(TreeNode tnParent, TreeViewTreeNode_ tvtnNote, int nImageIndex = 0)
        {
            TreeViewTreeNode_ tvtn = tvtnNote;

while(tvtn != null)
            {
                
                TreeNode tn = new TreeNode(tvtn.DispalyText);
                tn.Name = tvtn.KeyValue.ToString();
                tn.ForeColor = tvtn.DisplayForeColor;
                tn.BackColor = tvtn.DisplayBackColor;
                tn.NodeFont = tvtn.DispalyFont;

tn.ImageIndex = nImageIndex;
                tn.SelectedImageIndex = nImageIndex;
                tn.StateImageIndex = nImageIndex;

if (tnParent == null)
                    m_TreeView.Nodes.Add(tn);
                else
                    tnParent.Nodes.Add(tn);

BuildTreeView(tn, (TreeViewTreeNode_)tvtn.FirstChild, nImageIndex);

tvtn = (TreeViewTreeNode_)tvtn.NextSibling;
            }
             
        }

/// <summary>
        /// 
        /// </summary>
        /// <param name="isRecoverSelectd"></param>
        /// 创建时间:????-??-??     最后一次修改时间:2022-07-17  
        public void Dispaly(bool isRecoverSelectd = true)
        {

string  sSelectName = BuildInFile();

if (First == null)
            {
                lg.ShowInfo(" Dispaly       First == null             " +          KeyBinaryFullPathName);
            }

BuildTreeView(null,(TreeViewTreeNode_)First,13);

if(isRecoverSelectd)
            { 
                TreeNode[]  tnFind = m_TreeView.Nodes.Find(sSelectName,true);
            
                if(tnFind.Length > 0)
                {
                    m_TreeView.SelectedNode = tnFind[0];

if (tnFind[0].Parent != null)
                        tnFind[0].Parent.ForeColor = Color.Red;
                        //tnFind[0].Parent.NodeFont = new Font(tnFind[0].Parent.NodeFont, FontStyle.Bold);

tnFind[0].ForeColor = Color.Blue;
                    //tnFind[0].NodeFont = new Font(tnFind[0].NodeFont, FontStyle.Bold);
                }
            }
        }

public void Save()
        {
            if (IsModify)
            {
                KeyBinaryFile_ kbf = new KeyBinaryFile_(KeyBinaryFullPathName);

if(First != null)
                {
                    
                    kbf.addValue(ConstName + "_First", ((TreeViewTreeNode_)First).KeyValue.ToString());

if (m_TreeView != null)
                    {
                        if (m_TreeView.SelectedNode != null)
                            kbf.addValue(ConstName + "_Select", m_TreeView.SelectedNode.Name);
                        else

kbf.addValue(ConstName + "_Select", "-1");
                    }

SaveSiblingAndChild((TreeViewTreeNode_)First,kbf);

kbf.saveAsFile();  //只保留一份

kbf.ClearAll();
                    kbf = null;
                }
                else
                {
                    kbf.saveAsFile(kbf.FullPathName); //空文件
                }
            }
            IsModify = false;
        }

/// <summary>
        ///  清除结节
        /// </summary>
        /// 创建时间:2022-04-15     最后一次修改时间:2021-04-15 未测试
        public void Clear()
        {           
            ClearData(First);        
            First = null;

if(m_TreeView != null) m_TreeView.Nodes.Clear();          
        }

/// <summary>
        /// 遍历二叉树
        /// </summary>
        /// <param name="tn"></param>
        /// 创建时间:2022-04-15     最后一次修改时间:2021-04-15   未测试
        private void ClearData(TreeNode_ tn)
        {
            if (tn != null)
            {
                tn.Data = null;
                ClearData(tn.FirstChild);
                ClearData(tn.NextSibling);

tn.FirstChild = null;
                tn.NextSibling = null;
                
            }
        }

public void SaveSiblingAndChild(TreeViewTreeNode_ tvtnNode,KeyBinaryFile_ kbf)
        {
            TreeViewTreeNode_ tvtn = tvtnNode;

while (tvtn != null)
            {
                string sKeyString = ConstName + tvtn.SplitString + tvtn.KeyValue.ToString();
                kbf.addValue(sKeyString, tvtn.PackageData());

SaveSiblingAndChild((TreeViewTreeNode_)tvtn.FirstChild,kbf);

tvtn = (TreeViewTreeNode_)tvtn.NextSibling;
            }    
        }

/// <summary>
        /// 改变节点数据
        /// </summary>
        /// <param name="sData"></param>
        public void ChangeSelectedNodeData(string sData)
        {
            TreeNode tn = m_TreeView.SelectedNode;

if (tn == null)
                throw new Exception("tn == null");

TreeViewTreeNode_ tvtn = Find((TreeViewTreeNode_)First, m_TreeView.SelectedNode.Name);

if (tvtn == null)
                throw new Exception("tvtn == null");

tvtn.Data = sData;

if (tn.NodeFont != null)
            {
                tvtn.DispalyFont = tn.NodeFont;
            }
    
            tvtn.DispalyText = tn.Text;
            tvtn.DisplayBackColor = tn.BackColor;
            tvtn.DisplayForeColor = tn.ForeColor;

IsModify = true;

}

public void SetFirstData(string sData)
        {
            if (First != null)

First.Data = sData;

IsModify = true;
        }

/// <summary>
        /// TreeView控件的修改节点事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="Exception"></exception>
        /// 创建时间: ????-??-??      最后一次修改时间:2022-03-05
        public void AfterLabelEdit_Event(object sender, NodeLabelEditEventArgs e)
        { 
            if(e.Label != null && e.Label.Trim() != "")
            {
                UpdateTreeViewNote(e.Node, e.Label);              
                IsModify = true;
            }
            else
            {
                e.CancelEdit = true;
            }
        }

/// <summary>
        /// TreeView的节点属性改变,同时更新Tree_的节点。
        /// </summary>
        /// <param name="tnModify">发生改变的节点</param>
        /// <param name="sDispalyText">所显示的文本</param>
        /// <exception cref="Exception"></exception>
        /// 创建时间: 2022-03-05      最后一次修改时间:2022-03-05
        public void UpdateTreeViewNote(TreeNode tnModify, string sDispalyText = "")
        {
            TreeViewTreeNode_ tnFind = Find((TreeViewTreeNode_)First, tnModify.Name);

if (tnFind == null)
                throw new Exception("tnFind = null");

if (sDispalyText != "")
                tnFind.DispalyText = sDispalyText;
            else
                tnFind.DispalyText = tnModify.Text;

if (tnModify.NodeFont == null)  //如果没有设置时,新建的节点是NULL,自动跟TreeView的Font相同
            {
                tnFind.DispalyFont = m_TreeView.Font;
            }
            else
            {
                tnFind.DispalyFont = tnModify.NodeFont;
            }

tnFind.DisplayBackColor = tnModify.BackColor;
            tnFind.DisplayForeColor = tnModify.ForeColor;

}

public void TreeViewSelectedNodeAddNewNode(string sDisplayText = "新节点")
        {

TreeViewTreeNode_ tvtnNew = new TreeViewTreeNode_();
            tvtnNew.Data = "";
            tvtnNew.DispalyFont = m_TreeView.Font;
            tvtnNew.DispalyText = sDisplayText;
            tvtnNew.DisplayBackColor = m_TreeView.BackColor;
            tvtnNew.DisplayForeColor = m_TreeView.ForeColor;         
            tvtnNew.NextSibling = null;
          
            TreeNode tn = new TreeNode(sDisplayText);
            tn.Name = tvtnNew.KeyValue.ToString();

if (m_TreeView.SelectedNode == null)
            {

m_TreeView.Nodes.Add(tn);
                Add(null, tvtnNew);               
            }
            else
            {

m_TreeView.SelectedNode.Nodes.Add(tn);

TreeViewTreeNode_ tvtnParent = Find((TreeViewTreeNode_)First, m_TreeView.SelectedNode.Name);

if (tvtnParent == null)
                {
                    string sErrorInfo = "TreeDataView_中无法找到 m_TreeView.SelectedNode.Name= “" + m_TreeView.SelectedNode.Name + "” 的节点";
                    lg.ShowError(sErrorInfo, "TreeDataView_.TreeViewSelectedNodeAddNewNode");
                    lg.D(sErrorInfo, "TreeDataView_.TreeViewSelectedNodeAddNewNode");

return;
                }
                AddChild(tvtnParent, tvtnNew);

}

m_TreeView.SelectedNode = tn;
            IsModify = true;
        }

public void TreeViewAddNodeChild(TreeNode tnParent, string sChildDisplayText)
        {
            if (tnParent == null)
                throw new Exception("tnParent == null");

TreeViewTreeNode_ tvtnNew = new TreeViewTreeNode_();
            tvtnNew.Data = "";
            tvtnNew.DispalyFont = m_TreeView.Font;
            tvtnNew.DispalyText = sChildDisplayText;
            tvtnNew.DisplayBackColor = m_TreeView.BackColor;
            tvtnNew.DisplayForeColor = m_TreeView.ForeColor;
            tvtnNew.NextSibling = null;

TreeNode tn = new TreeNode(sChildDisplayText);
            tn.Name = tvtnNew.KeyValue.ToString();
             
            TreeViewTreeNode_ tvtnParent = Find((TreeViewTreeNode_)First, m_TreeView.SelectedNode.Name);

if (tvtnParent == null)
                throw new Exception("tvtnParent = null");

AddChild(tvtnParent, tvtnNew);

tnParent.Nodes.Add(tn);
        }

/// <summary>
        /// 改变字体或者前景色
        /// </summary>
        /// <param name="tnNode"></param>
        public void TreeViewNodeAttributeChange(TreeNode tnNode)
        {
            TreeViewTreeNode_ tn = Find((TreeViewTreeNode_)First, tnNode.Name);

if(tn != null)
            {
                tn.DispalyFont = tnNode.NodeFont;
                tn.DispalyText = tnNode.Text;
                tn.DisplayForeColor = tnNode.ForeColor;
                tn.DisplayBackColor = tnNode.BackColor;

IsModify = true;
            }
        }

/// <summary>
        /// 把选中的节点上移一位
        /// </summary>
        /// <returns></returns>
        /// 创建时间:2022-07-17 最后一次修改时间:2022-07-19
        public string TreeViewSelectNoteMoveUp()
        {

TreeNode tnSelect = m_TreeView.SelectedNode;
             
            if(tnSelect == null)
            {
                return "未先定节点";
            }

TreeViewTreeNode_ tvtnSelect = Find((TreeViewTreeNode_)First, tnSelect.Name);

TreeViewTreeNode_ tvtnSelectParent = (TreeViewTreeNode_)FindPrent(First, tvtnSelect);

if (tvtnSelectParent == null) return "未找到父结点!";

if (tvtnSelect == null) return "未找到值为:+ " + tnSelect.Name + " 的节点!";

TreeViewTreeNode_ prevOne = (TreeViewTreeNode_)FindPrevSibling(First, tvtnSelect);

if (prevOne == null)  return "上一个兄弟结点不存在,无法上移!";

TreeViewTreeNode_ prevTwo = (TreeViewTreeNode_)FindPrevSibling(First, prevOne);
            
            if (prevTwo == null)  
            {
                //-----------------------------在TreeView中
                TreeNode tnParent = tnSelect.Parent;
                int nInsertIndex = tnSelect.Index - 1;

if (tnParent != null)
                {
                    TreeNode newNode = (TreeNode)tnSelect.Clone();    //克隆选中的节点
                    tnParent.Nodes.Insert(nInsertIndex, newNode);                    
                    tnSelect.Remove();

//------------------------------------------在 Tree中
                    //交换的是第一个结点,要找出它的父结点

Int64 iTempKey = tvtnSelect.NextSiblingKeyValue;
                    tvtnSelectParent.FirstChildKeyValue = tvtnSelect.KeyValue;
                    tvtnSelect.NextSiblingKeyValue = prevOne.KeyValue;
                    prevOne.NextSiblingKeyValue = iTempKey;

TreeNode_ tnTemp = tvtnSelect.NextSibling;
                    tvtnSelectParent.FirstChild = tvtnSelect;
                    tvtnSelect.NextSibling = prevOne;
                    prevOne.NextSibling = tnTemp;

m_TreeView.SelectedNode = newNode;
                }                 
              
            }
            else
            {
                //-----------------------------在TreeView中
                TreeNode tnParent = tnSelect.Parent;
                int nInsertIndex = tnSelect.Index - 1;

if (tnParent != null)
                {
                    TreeNode newNode = (TreeNode)tnSelect.Clone();    //克隆选中的节点
                    tnParent.Nodes.Insert(nInsertIndex, newNode);
                    tnSelect.Remove();

//------------------------------------------在 Tree中
                    //交换中间结点,要找出它的父结点

Int64 iTempKey = tvtnSelect.NextSiblingKeyValue;
                    prevTwo.NextSiblingKeyValue = tvtnSelect.KeyValue;
                    tvtnSelect.NextSiblingKeyValue = prevOne.KeyValue;
                    prevOne.NextSiblingKeyValue = iTempKey;

TreeNode_ tnTemp = tvtnSelect.NextSibling;
                    prevTwo.NextSibling = tvtnSelect;
                    tvtnSelect.NextSibling = prevOne;
                    prevOne.NextSibling = tnTemp;

m_TreeView.SelectedNode = newNode;
                }
            }

return "";
        }

/// <summary>
        /// 把选中的节点下移一位
        /// </summary>
        /// <returns></returns>
        /// 创建时间:2022-07-17 最后一次修改时间:2022-07-19
        public string TreeViewSelectNoteMoveDown()
        {

TreeNode tnSelect = m_TreeView.SelectedNode;

if (tnSelect == null)
            {
                return "未先定节点";
            }

TreeViewTreeNode_ tvtnSelect = Find((TreeViewTreeNode_)First, tnSelect.Name);

TreeViewTreeNode_ tvtnSelectParent = (TreeViewTreeNode_)FindPrent(First, tvtnSelect);

if (tvtnSelectParent == null) return "未找到父结点!";

if (tvtnSelect == null) return "未找到值为:+ " + tnSelect.Name + " 的节点!";

TreeViewTreeNode_ nextOne = (TreeViewTreeNode_)tvtnSelect.NextSibling;

if (nextOne == null) return "下一个兄弟结点不存在,无法下移!";

TreeViewTreeNode_ prevOne = (TreeViewTreeNode_)FindPrevSibling(First, tvtnSelect);

if (prevOne == null)  //第一节点移到下面
            {
                //-----------------------------在TreeView中
                TreeNode tnParent = tnSelect.Parent;
                int nInsertIndex = tnSelect.Index + 2;

if (tnParent != null)
                {
                    TreeNode newNode = (TreeNode)tnSelect.Clone();    //克隆选中的节点
                    tnParent.Nodes.Insert(nInsertIndex, newNode);
                    tnSelect.Remove();

//------------------------------------------在 Tree中
                    //交换的是第一个结点,要找出它的父结点

Int64 iTempKey = nextOne.NextSiblingKeyValue;
                    tvtnSelectParent.FirstChildKeyValue = nextOne.KeyValue;  
                    nextOne.NextSiblingKeyValue = tvtnSelect.KeyValue;
                    tvtnSelect.NextSiblingKeyValue = iTempKey;

TreeNode_ tnTemp = nextOne.NextSibling;
                    tvtnSelectParent.FirstChild = nextOne;
                    nextOne.NextSibling = tvtnSelect;
                    tvtnSelect.NextSibling = tnTemp;

m_TreeView.SelectedNode = newNode;
                }

}
            else
            {
                //-----------------------------在TreeView中
                TreeNode tnParent = tnSelect.Parent;
                int nInsertIndex = tnSelect.Index + 2;

if (tnParent != null)
                {
                    TreeNode newNode = (TreeNode)tnSelect.Clone();    //克隆选中的节点
                    tnParent.Nodes.Insert(nInsertIndex, newNode);
                    tnSelect.Remove();

//------------------------------------------在 Tree中
                    //交换中间结点

Int64 iTempKey = nextOne.NextSiblingKeyValue;
                    prevOne.NextSiblingKeyValue = nextOne.KeyValue;
                    nextOne.NextSiblingKeyValue = tvtnSelect.KeyValue;
                    tvtnSelect.NextSiblingKeyValue = iTempKey;

TreeNode_ tnTemp = nextOne.NextSibling;
                    prevOne.NextSibling = nextOne;
                    nextOne.NextSibling = tvtnSelect;
                    tvtnSelect.NextSibling = tnTemp;

m_TreeView.SelectedNode = newNode;
                }
            }

return "";
        }

public void TreeViewSelectedNodeDelete()
        {              
            TreeNode tn = m_TreeView.SelectedNode;
            if (tn != null)
            {
                if (MessageBox.Show("真的要删除“" + tn.Text + "”吗?", "删除提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    
                    m_TreeView.Nodes.Remove(tn);

if (First == null)
                        throw new Exception("First==null");

TreeViewTreeNode_ tnRemove = Find((TreeViewTreeNode_)First, tn.Name);
                    if (tnRemove == null)
                        throw new Exception("tnRemove == null");

if (!RemoveNote(tnRemove))
                    {
                        throw new Exception(" RemoveNote(tnRemove) == False");
                    }
                    
                    IsModify = true;
                }
            }
        }

public TreeNode TreeViewAddRootNode(string sText = "")
        {
            TreeViewTreeNode_ tvtnNew = GetinitTreeViewTreeNode(sText);

Add(null, tvtnNew);

TreeNode tnNew;

if (sText != "")
                tnNew = m_TreeView.Nodes.Add(sText);
            else
                tnNew = m_TreeView.Nodes.Add("新节点");

tnNew.Name = tvtnNew.KeyValue.ToString();

IsModify = true;

return tnNew;
        }

public string GetTreeNodeData(TreeNode tn)
        {
            TreeViewTreeNode_ tvtn = Find((TreeViewTreeNode_)First, tn.Name);

if (tvtn == null)
                throw new Exception("tvtn == null");

return tvtn.Data;
        }

public void SetTreeNodeData(TreeNode tn, string sData)
        {
            TreeViewTreeNode_ tvtn = Find((TreeViewTreeNode_)First, tn.Name);

if (tvtn == null)
                throw new Exception("tvtn == null");

tvtn.Data = sData;

IsModify = true;
        }

public string GetFirstNodeData()
        {
            if (First != null)
                return First.Data;
            else
                return "";
        }

public void DragDrop_Event(object sender, DragEventArgs e)
        {
            //获得拖放中的节点
            TreeNode tnMove = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");

//根据鼠标坐标确定要移动到的目标节点
            Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));

TreeNode tnTarget = m_TreeView.GetNodeAt(pt);

if (tnTarget == null) {  return; }

if (tnMove.Nodes.Find(tnTarget.Name, true).Length != 0)
            {
                lg.ShowError("无法移动父节点到到它子节点中去!", null);
                return;
            }

//不需要变动,因为把tnMove放在tnTarget下为子节点,而tnMove本身就是tnTarget的最后一个子节点。
            if (tnTarget.Nodes.Count > 0 && tnTarget.Nodes[tnTarget.Nodes.Count - 1] == tnMove)
                return;

//----------------------------------------------------------------在Tree_上操作
            TreeViewTreeNode_ ltnMove = Find((TreeViewTreeNode_)First, tnMove.Name);

if(ltnMove == null)
            {
                throw new Exception("无法找到节点:" + tnMove.Text);
            }

//除去ltnMove

TreeViewTreeNode_ ltnPrevSibling = (TreeViewTreeNode_)FindPrevSibling(First, ltnMove);

if (ltnPrevSibling != null)
            {               
                ltnPrevSibling.NextSibling = ltnMove.NextSibling;
                ltnPrevSibling.NextSiblingKeyValue = ltnMove.NextSiblingKeyValue;

//一定要设置ltnMove为孤链
                ltnMove.NextSibling = null;
                ltnMove.NextSiblingKeyValue = -1;
            }
            else
            { 
                TreeViewTreeNode_ ltnParent = (TreeViewTreeNode_)FindIsFirstChild(First, ltnMove);

if (ltnParent != null)
                {     
                    if (ltnMove.NextSibling != null)
                    {
                  
                        ltnParent.FirstChild = ltnMove.NextSibling;
                        ltnParent.FirstChildKeyValue = (ltnMove.NextSibling as TreeViewTreeNode_).KeyValue;

//一定要设置ltnMove为孤链
                        ltnMove.NextSibling = null;
                        ltnMove.NextSiblingKeyValue = -1;
                    }
                    else
                    {
                        ltnParent.FirstChild = null;
                        ltnParent.FirstChildKeyValue = -1;
                    }
                }
                else
                {
                    throw new Exception("链接错误!");
                }
            }

//查找目标节点
            TreeViewTreeNode_ ltnTarget = (TreeViewTreeNode_)Find((TreeViewTreeNode_)First, tnTarget.Name);

if (ltnTarget == null)
            {
                throw new Exception("无法找到节点:" + tnTarget.Text);
            }

//在目标节点未加上子节点ltnMove
            AddChild((TreeViewTreeNode_)ltnTarget, (TreeViewTreeNode_)ltnMove);

//-------------------------------------------------------------在控件上操作

//如果目标节点为分组则添加到下级节点的未端,如果目标节点为素材文件则添加为同级节点
            TreeNode NewMoveNode = (TreeNode)tnMove.Clone();

tnTarget.Nodes.Insert(tnTarget.Nodes.Count, NewMoveNode);

//更新当前拖动的节点选择
            m_TreeView.SelectedNode = NewMoveNode;
            //展开目标节点,便于显示拖放效果
            tnTarget.Expand();

//移除拖放的节点
            tnMove.Remove();

IsModify = true;

}

public void ItemDrag_Event(object sender, ItemDragEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                m_TreeView.DoDragDrop(e.Item, DragDropEffects.Move);
            }
        }

public void DragEnter_Event(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode)))
                e.Effect = DragDropEffects.Move;
            else
                e.Effect = DragDropEffects.None;
        }

public TreeViewTreeNode_ GetinitTreeViewTreeNode(string sText)
        {
            TreeViewTreeNode_ tvtnNew = new TreeViewTreeNode_();

if (sText != "")
                tvtnNew.DispalyText = sText;
            else
                tvtnNew.DispalyText = "新节点";

if (m_TreeView.Font == null)
                throw new Exception("m_TreeView.Font== null");
            tvtnNew.DispalyFont = m_TreeView.Font;
            tvtnNew.DisplayBackColor = m_TreeView.BackColor;
            tvtnNew.DisplayForeColor = m_TreeView.ForeColor;

return tvtnNew;
        }

public void WriteToFile(KeyBinaryFile_ kbf)
        {
             
        }

public void ReadFromFile(KeyBinaryFile_ kbf)
        {

}

public void ReadFromTreeView(TreeView tv)
        {
            
        }

public TreeDataView_(string sFullPathName, TreeView tvDisplayTreeView)
        {
            KeyBinaryFullPathName = sFullPathName;

First = null;

m_TreeView = tvDisplayTreeView;

if (m_TreeView != null)
            {
                m_TreeView.Nodes.Clear();
            }       
             
        }

public void SetDisplayTreeView(TreeView tvDisplayTreeView)
        {
            m_TreeView = tvDisplayTreeView;

if(m_TreeView != null)
            {
                m_TreeView.Nodes.Clear();
            }
        }

};

}

#endif

Tree_ 打包TreeView控件 C#相关推荐

  1. dev treeview控件_在Winform开发框架中使用DevExpress的TreeList和TreeListLookupEdit控件

    DevExpress提供的树形列表控件TreeList和树形下拉列表控件TreeListLookupEdit都是非常强大的一个控件,它和我们传统Winform的TreeView控件使用上有所不同,我一 ...

  2. C# 在DataGridView中,点击单元格调出 TreeView控件 或 ListBox控件

    1.调出 TreeView控件 或  ListBox控件 private void deductGrid1_CellClick(object sender, DataGridViewCellEvent ...

  3. 递归遍历文件夹,并添加到TreeView控件中

    遍历文件夹,并把所有节点增加到TreeView控件中,这里单独写成了一个静态类,传入根目录节点和指定的目录这两个参数即可,可以稍作扩展用于其他方案 View Code 1 using System; ...

  4. WinForm开发中针对TreeView控件改变当前选择节点的字体与颜色

    WinForm开发中针对TreeView控件改变当前选择节点的字体与颜色  在B/S开发中,对TreeView控件要改变当前选中节点的颜色比较方便,其有相应的SelectedNodeChanged事件 ...

  5. matlab treeview,treeview控件

    高分在线等:C#中如何给treeview控件上的节点前添比如有一treeview1控件,需要在其所有节点前均加一静态小图标(所有节点我也新手,正好刚用过这功能.如下: 1. 到工具箱中拖一个image ...

  6. C# 系统应用之TreeView控件 (一).显示树状磁盘文件目录及加载图标

    在C#系统应用毕设U盘防御软件中需要实现文件不可恢复的删除,首先需要实现类似于资源管理器的界面,通过TreeView控件显示"我的电脑"所有磁盘文件树状目录并加载相应图标.显示结果 ...

  7. TreeView控件的展开与折叠

    在窗体中添加一个TreeView控件,设置CheckBox属性为True,绑定数据 Archive jkj = new Archive();//自定义类         public void Bin ...

  8. 给TreeView控件绑定数据

    TreeView控件显示Node对象的等级体系结构,每个Node对象包含了一个标签和可选的点位图.TreeView控件通常用于显示文档头.索引中的条目.磁盘上的文件和目录或者可以显示为等级结构的各种其 ...

  9. 部门树形结构,使用Treeview控件显示部门

    部门树形结构.设计张部门表用于存储部门编码.名称.上级部门id,使用Treeview控件显示部门树,并实现部门增删改.移动.折叠等功能.特别提示,部门有层级关系,可用donetbar的adtree控件 ...

最新文章

  1. 工作5年才有自己博客...汗...
  2. Java浅克隆与深克隆区别详解与实现,以及String类型属性克隆为什么不受影响?克隆clone()方法中为什么是super.clone()
  3. C++ STL学习之容器set和multiset (补充材料)
  4. 关于restful协议很多人的误解
  5. 回归素材(part2)--机器学习与R语言
  6. mysql 常用命令的使用_MySQL基本命令
  7. Python3.x爬虫教程:爬网页、爬图片、自己主动登录
  8. 北京地铁规划大全(图),买房子可以参考一下
  9. still a week before on board
  10. PYG解密小组的Visual Assist X插件完全卸载
  11. 判断浏览器内核是否是IE8及其以下
  12. 教你制作一个自动发摩斯电码的PYTHON小程序
  13. Spring Cloud 快速入门指南(一)
  14. Week 10. 第189-204题
  15. c语言sqrt是double,实现double sqrt(double num)
  16. VMware连接不上网络解决办法
  17. do还是doing imagine加to_to-do和doing用法及区别
  18. MBR+双硬盘(固态+机械)双系统(win+ubuntu21.04)装机教程
  19. 【Ansible】 Ansible 模块 setup 与 stat 模块用法
  20. 跨境电商独立站模式分析

热门文章

  1. 从程序员到系统分析员(转)
  2. 三维住房模型中的构件如何线框显示?
  3. html做微信logo,纯CSS实现一个微信logo,需要几个标签?_html/css_WEB-ITnose
  4. 彻底理解0-1背包问题
  5. excel怎么批量提取指定网站内容-免费指定网站提取导出excel软件
  6. HDU2060 Snooker斯诺克
  7. 计算机应用技能大赛方案,小学电脑技能大赛活动方案
  8. SpringBoot 集成 ElasticSearch 全文搜索(步骤非常的详细)
  9. 田野调查手记·浮山摩崖石刻(十六)
  10. html文档转换word,如何把HTML文档转换成Word文件?