如何在 Treeview.Sort 后将 Treeview 重置为默认显示?

How to reset Treeview to default display after Treeview.Sort?

我试图按字母顺序显示树视图的节点并设法通过以下方式简单地完成它:

treeview1.Sort();  

它负责排序。但我希望可以选择将树视图恢复到其原始显示状态(不按字母顺序排序)。

on another question 我看到我可以使用树视图的 属性: .sorted 并将其设置为 true 或 false 但它对我没有任何作用。

我在控件中有数据,它已经在设计时设置了。

最好的方法是什么?

非常感谢!

当然,从外部来源获取内容是填充 Tree 最灵活的方式,但是..

..由于树的内容已添加到设计器中,因此如果涉及大量数据,最好的方法可能是通过将设计器代码移动到神奇的 Unsort 中来挽救这些数据-您可以随时调用的功能。

好好看看表格的 Designer.cs 文件!在这里您可以找到两个处理 TreeView:

加载的部分
  • 第一个坐在 'forbidden' 部分内:InitializeComponent()带有可怕的警告,你不应该改变那里的任何东西。好吧,别担心,我们所做的只是从中复制几行到 unsort 函数..

我们需要的是声明和创建节点的所有行。它们看起来像这样:

System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("John");

现在向下滚动到以

开头的部分
   // 
   // treeView1
   // 

我们不关心将 NameLocation 分配给 TreeView 的前几行。但是我们想要 all 以下行设置 NamesallTextsNodes ;以及将根节点添加到 TreeView..

的所有行

我们将所有这些复制到一个函数中,该函数首先清除 Nodes 并重置 Sorted 属性。然后是我们从设计师那里抢救出来的所有台词。

结果可能如下所示:

void unsortTree()
{
   this.treeView1.Nodes.Clear();
   this.treeView1.Sorted = false;
    
   System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("John");
   System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Paul");
   System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("George");
   System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("Ringo");
   System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("Beatles",
                 new System.Windows.Forms.TreeNode[] 
                 {treeNode1,  treeNode2, treeNode3, treeNode4});
   System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("Byrds");
   System.Windows.Forms.TreeNode treeNode7 = 
         new System.Windows.Forms.TreeNode("Bee Gees");

   // 
   // treeView1
   // 

   treeNode1.Name = "Knoten2";        treeNode1.Text = "John";
   treeNode2.Name = "Knoten3";        treeNode2.Text = "Paul";
   treeNode3.Name = "Knoten4";        treeNode3.Text = "George";
   treeNode4.Name = "Knoten6";        treeNode4.Text = "Ringo";
   treeNode5.Name = "Knoten0";        treeNode5.Text = "Beatles";
   treeNode6.Name = "Knoten1";        treeNode6.Text = "Byrds";
   treeNode7.Name = "Knoten7";        treeNode7.Text = "Bee Gees";

   this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[]
                                { treeNode5,   treeNode6, treeNode7});

}

我们已经测试过这可以正常工作,您可以从设计器中的树中删除节点并将对该函数的调用添加到表单加载中。不要将数据保存在两个地方!!

注意:因为这会从头开始重新创建树内容,所有 用户输入 都将丢失。如果用户可以检查 CheckBoxes 或编辑 Labels 你应该考虑写一个 treesave 和 treeload 函数! (不一定针对文件,可能只是一个不可见的 helper-treeview..)

注2:

由于 TreeView 确实包含 CheckBoxes(但既不添加也不删除 Nodes 也不更改 Texts)我们应该存储和恢复 CheckStates .

在 class 级别添加一个 Dictionary 和这两个递归辅助函数几乎是我们所需要的:

Dictionary<string, bool> tvCheckStates = null;

void storeChecks(TreeNode node)
{
    if (tvCheckStates.Keys.Contains(node.Name))
        throw new Exception("duplicate node name:" + node.Name);
    else tvCheckStates.Add(node.Name, node.Checked);

    foreach (TreeNode n in node.Nodes) storeChecks(n);
}

void restoreChecks(TreeNode node)
{
    if (tvCheckStates.Keys.Contains(node.Name))
        node.Checked = tvCheckStates[node.Name];
    else throw new Exception("node not found:" + node.Name);

    foreach (TreeNode n in node.Nodes) restoreChecks(n);
}

最后我们在 'unsort' 的开头和结尾调用它们:

  {
      if (tvCheckStates == null && treeView1.Nodes.Count > 0) 
          tvCheckStates = new Dictionary<string, bool>();
      else if (treeView1.Nodes.Count > 0) tvCheckStates.Clear();
      foreach (TreeNode node in treeView1.Nodes) storeChecks(node);
      //..

      //..
      if (tvCheckStates != null && treeView1.Nodes.Count > 0) 
          foreach (TreeNode node in treeView1.Nodes) restoreChecks(node);
  }

请注意 Node Names 必须 唯一(他们应该如此)。

要在程序运行期间保持状态,保存已检查节点的名称应该就足够了。