如果在 A 下的 C 下加入 D,如果只是在 TreeView 上改變顯示,那麼要遍歷整個 Tree,找出所有的 C (B 下有一個 C)之後,改變畫面,雖然可以這樣做,但程式碼上似乎複雜了點
所以改變思路,在 C 下加入 D 之後,重新綁定 TreeView 的資料。
但是重新綁定 TreeView 之後,TreeView 會收合到剩下第一層,使用者就要重新展開之後,再往下加入其他子項目,這點其實很麻煩。
所以在重新綁定前先記錄下目前 TreeView 的展開狀態,綁定之後再還原展開狀態,程式碼加下
設定兩個全域變數
private Dictionary<string, bool> NodesStatus = new Dictionary<string, bool>(); // 記錄展開狀態 private string SelectNodeFullPath = ""; // 記錄選擇到的節點
記錄展開狀態
/// <summary> /// 記錄展開狀態 /// </summary> /// <param name="nodes"></param> private void GetTreeNodesStatus(TreeNodeCollection nodes) { foreach (TreeNode node in nodes) { if (node.IsExpanded) { NodesStatus[node.FullPath] = true; } else { NodesStatus.Remove(node.FullPath); } if (node.IsSelected) { SelectNodeFullPath = node.FullPath; } GetTreeNodesStatus(node.Nodes); } }
還原展開狀態
/// <summary> /// 還原展開狀態 /// </summary> /// <param name="nodes"></param> private void SetTreeNodesStatus(TreeNodeCollection nodes) { foreach (TreeNode node in nodes) { if (NodesStatus.ContainsKey(node.FullPath)) { node.Expand(); } if (node.FullPath == SelectNodeFullPath) { treeView1.SelectedNode = node; } SetTreeNodesStatus(node.Nodes); } }
使用方式
// 對treeView1做了某些操作之後(例如加入子選項) GetTreeNodesStatus(treeView1.Nodes); BindTreeViewData(); // 綁定TreeView SetTreeNodesStatus(treeView1.Nodes);