6

TreeViewを含むプログラムがあります。ルートとルートの下の2つのノードを除くすべてのノードがデータベースからロードされます。

ユーザーがデータベースにデータを追加するとき、そのデータはTreeViewに自動的に追加される必要があります。すべてのノードをクリアし、デフォルトノードを追加し、新しいノードを含むすべてのデータをTreeViewに追加することでこれを正常に行うことができますが、新しいTreeViewのすべてのノードが折りたたまれています。

クライアントは、拡張されたすべてのノードを保持したいが、追加したばかりの新しいデータを追加したいと考えています。展開されたすべてのノードを知り、折りたたまれたり更新されたりしたら、再度展開する方法はありますか?ご回答ありがとうございます。

4

6 に答える 6

6

こんにちは、ツリービューを更新した後(新しいデータを追加するか、一部を削除して)、ツリービューマップを保存したいことを理解しています。展開されたすべてのノードを展開したいのですが、他のノードはデフォルトで折りたたまれています。解決策は次のとおりです。

1) 更新前に展開されたツリー ビュー ノードを保存する

2) ツリー ビュー データを更新します (ノードを削除する場合は、保存済みリストからも削除することに注意してください)。

3) 以前に保存したツリー ビュー マップを設定する

ツリー ビュー マップの保存 (展開されたノードのみ) -> このコード ツリー ビュー ノード コレクションを参照し、展開されたノード名を文字列リストに保存します。

List<string> collectExpandedNodes(TreeNodeCollection Nodes)
        {
            List<string> _lst = new List<string>();
            foreach (TreeNode checknode in Nodes)
            {
                if (checknode.IsExpanded)
                    _lst.Add(checknode.Name);
                if (checknode.Nodes.Count > 0)
                    _lst.AddRange(collectExpandedNodes(checknode.Nodes));
            }
            return _lst;
        }

展開されたノード名をリストに収集し、ツリー ビューの外観を取り戻したい場合は、名前でノードを取得する関数と、選択したノードとその親を展開する関数の 2 つの関数が必要です。

この関数は、ノードがツリー ノード コレクションに存在する場合、選択したノード名へのポインタを取得します。

TreeNode FindNodeByName(TreeNodeCollection NodesCollection , string Name)
        {
          TreeNode returnNode = null; // Default value to return
          foreach (TreeNode checkNode in NodesCollection)
            {
                if (checkNode.Name == Name)  //checks if this node name is correct
                    returnNode = checkNode;
                else if (checkNode.Nodes.Count > 0 ) //node has child
                {
                    returnNode = FindNodeByName(checkNode.Nodes , Name);
                }

              if (returnNode != null) //check if founded do not continue and break
              {
                  return returnNode;
              }

            }
            //not found
            return returnNode;
        }

およびこの関数展開ノードとその親

void expandNodePath(TreeNode node)
        {
            if (node == null)
                return;
            if (node.Level != 0) //check if it is not root
            {
                node.Expand();
                expandNodePath(node.Parent);
            }
            else
            {
                node.Expand(); // this is root 
            }

        }

以下は、関数の使用法を示しています

private void button4_Click(object sender, EventArgs e)
        {
            //saving expanded nodes
            List<string> ExpandedNodes = new List<string>();
            ExpandedNodes = collectExpandedNodes(treeView1.Nodes);
            //resetting tree view nodes status to colapsed
            treeView1.CollapseAll();

            //Restore it back
            if (ExpandedNodes.Count > 0)
            {
                TreeNode IamExpandedNode;
                for (int i = 0; i < ExpandedNodes.Count;i++ )
                {
                    IamExpandedNode = FindNodeByName(treeView1.Nodes, ExpandedNodes[i]);
                    expandNodePath(IamExpandedNode);
                }

            }

        }
于 2013-01-30T13:48:46.020 に答える
3

すべてのノードを展開するには、以下のコードを使用します

treeView1.ExpandAll();

選択したノードを展開するには、以下のコードを使用します

treeView1.SelectedNode.ExpandAll();

特定のノードを展開するには、以下のコードを使用します

treeView1.Nodes[Index].Expand();
于 2013-01-30T04:59:03.117 に答える
2

Nodename が一意であると仮定します。

  • データベースを使用すると、ノード名をテーブルの一意の行 ID にすることができます
  • ツリー (リスト) の状態は、フォーマッター (例: BinaryFormatter ) で簡単に保存できます。
    • ユーザーがステータスを保存したい場合

展開された状態のみを保存します

private List<string> SaveTreeState(TreeNodeCollection nodes)
{
  List<string> nodeStates = new List<string>();
  foreach (TreeNode node in nodes)
  {
    if (node.IsExpanded) nodeStates.Add(node.Name);
    nodeStates.AddRange(SaveTreeState(node.Nodes));
  }
  return (nodeStates);
}

復元するノードを見つける作業はツリービューに任せます

private void RestoreTreeState(TreeView tree, List<string> treeState)
{
  foreach (string NodeName in treeState)
  {
    TreeNode[] NodeList = treeView1.Nodes.Find(NodeName, true);
    if (NodeList.Length > 0) // only if node after reload is avail
      NodeList[0].Expand(); 
  }
}

使用:

List<string> StateList = SaveTreeState(treeView1.Nodes);
... // reload
RestoreTreeState(treeView1, StateList);
于 2014-09-12T11:25:11.190 に答える
1

とても簡単です。以下に、私の再帰バージョンを示します。

//List of storage ids of expanded nodes
List<int> expandedNodeIds = new List<int>();
//call recursive fun for our tree
CollectExpandedNodes(tree.Nodes);
//recursive fun for collect expanded node ids
private void CollectExpandedNodes(TreeListNodes nodes)
{
   foreach (TreeListNode node in nodes)
   {
      if (node.Expanded) expandedNodeIds.Add(node.Id);
      if (node.HasChildren) CollectExpandedNodes(node.Nodes);
   }
}
于 2014-03-06T07:09:44.733 に答える
1

ノードを単純に展開するには、次のコードを試すことができます

 private void button1_Click(object sender, EventArgs e)
{
  treeView1.Nodes.Add(new TreeNode("New Node",
    new TreeNode[2] { new TreeNode("Node1"), new TreeNode("Node2") }));
  treeView1.Nodes[1].Expand();
}

それが役立つことを願っています

于 2013-01-30T04:34:50.903 に答える