当然,从外部来源获取内容是填写Tree 最灵活的方式,但是..
..由于树的内容已添加到设计器中,因此如果涉及大量数据,最佳途径可能是将设计器代码移动到神奇的Unsort-函数中来挽救这些数据,您可以随时打电话。
仔细查看表单的Designer.cs 文件!在这里您可以找到两个处理TreeView 加载的部分:
- 第一个坐在“禁止”部分内:
InitializeComponent()带有可怕的警告,您不应该更改其中的任何内容。好吧,别担心,我们所做的只是将其中的几行复制到 unsort 函数中。
我们需要的是所有声明和创建节点的行。它们看起来像这样:
System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("John");
现在向下滚动到开头的部分
//
// treeView1
//
我们不关心将Name 和Location 分配给TreeView 的前几行。但是我们想要 all 以下几行来设置 all 的 Names 和 Texts Nodes;以及将根节点添加到 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 函数! (不一定针对文件,可能只是一个不可见的辅助树视图..)
注2:
由于TreeView 确实包含CheckBoxes(但既不添加也不删除Nodes 也不更改Texts)我们应该存储和恢复CheckStates。
在类级别添加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 必须是唯一的(应该如此)。
要在程序运行中保持状态,保存已检查节点的名称就足够了..