C# 基于纯文本在TreeView中显示TFS测试用例';文件夹';财产
我们部门使用的测试用例从SpiraTeam迁移到TFS中。SpiraTeam允许将测试用例存储在文件夹层次结构中,例如 订购/订购和库存/发送订单/测试1:发送正常订单 TFS不支持此层次结构,因此,在迁移过程中,我们将每个测试的文件夹层次结构复制为纯文本,现在将其存储在名为“文件夹”的TFS工作项中的纯文本字段中 我正在开发一个小型C#应用程序,它允许在这个层次结构中查看和编辑测试用例 我计划从层次结构构建一个树视图来显示测试用例 我拥有检索测试用例的所有功能,目前将它们存储在应用程序内的WorkItemStore中,但我有两个问题:C# 基于纯文本在TreeView中显示TFS测试用例';文件夹';财产,c#,tfs,treeview,C#,Tfs,Treeview,我们部门使用的测试用例从SpiraTeam迁移到TFS中。SpiraTeam允许将测试用例存储在文件夹层次结构中,例如 订购/订购和库存/发送订单/测试1:发送正常订单 TFS不支持此层次结构,因此,在迁移过程中,我们将每个测试的文件夹层次结构复制为纯文本,现在将其存储在名为“文件夹”的TFS工作项中的纯文本字段中 我正在开发一个小型C#应用程序,它允许在这个层次结构中查看和编辑测试用例 我计划从层次结构构建一个树视图来显示测试用例 我拥有检索测试用例的所有功能,目前将它们存储在应用程序内的Wo
Andy下面是一个可以在LinqPad中运行的示例程序。它接受一个WorkItem(在本例中是我创建的一个类),并在通过
/
拆分它之后沿着路径遍历,在前进的过程中沿行创建节点,如果它在同一集合中找到具有相同文本的节点,它将改为使用该节点
void Main()
{
//Create a treeview with a root node.
TreeView tv = new TreeView();
tv.ShowNodeToolTips = true; //Turn on tooltips for this demo.
tv.Nodes.Add(new TreeNode("Root"));
//These may need ordering by path before you start.
var tfsTestCases = new[]
{
new WorkItem { Path = "Module/Feature1/SubFeature1/Test1", WorkItemId = 1, },
new WorkItem { Path = "Module/Feature1/SubFeature1/Test2", WorkItemId = 2, },
new WorkItem { Path = "Module/Feature1/SubFeature2/Test1", WorkItemId = 3, },
new WorkItem { Path = "Module/Feature1/SubFeature2/Test2", WorkItemId = 4, },
new WorkItem { Path = "Module/Feature2/SubFeature1/Test1", WorkItemId = 5, },
new WorkItem { Path = "Module/Feature2/SubFeature1/Test2", WorkItemId = 6, },
};
//Looping through the test cases...
foreach (var testCase in tfsTestCases)
{
//Start at the root of the tree for each work item.
TreeNode lastNode = tv.Nodes[0];
//Loop through each part of the path and create a new node.
//Use the NodeCollection from the one we just created each time through the loop.
//This allows the next iteration to "walk down" as it goes.
foreach (var part in testCase.Path.Split('/'))
lastNode = AddTreeNode(lastNode.Nodes, part);
//Set the Tag on the last node in the loop, this is the one with the actual Test Case.
//You can reference the Tag property of "tv.SelectedNode" to get access to the Work Item. If the Tag is null, then it's not a Test Case.
lastNode.Tag = testCase;
lastNode.ToolTipText = testCase.WorkItemId.ToString(); //Set for this DEMO.
}
//Display the tree.
tv.Dump();
}
TreeNode AddTreeNode(TreeNodeCollection nodes, String path)
{
//Try and find a node in the collection matching the specified pathPath.
var node = nodes.Cast<TreeNode>().Where(node => node.Text == path).SingleOrDefault();
//If it's not found, create it and add it to the collection of nodes we just searched.
if (node == null)
{
node = new TreeNode(path);
nodes.Add(parentNode);
}
//We need this later, so pass it back.
return node;
}
class WorkItem
{
public String Path { get; set; }
public Int32 WorkItemId { get; set; }
//etc.
}
void Main()
{
//创建具有根节点的树视图。
TreeView tv=新的TreeView();
tv.ShowNodeToolTips=true;//打开此演示的工具提示。
添加(新树节点(“根”);
//在开始之前,可能需要按路径进行排序。
var tfsTestCases=new[]
{
新工作项{Path=“Module/Feature1/SubFeature1/Test1”,工作项ID=1,},
新工作项{Path=“Module/Feature1/SubFeature1/Test2”,工作项ID=2,},
新工作项{Path=“Module/Feature1/SubFeature2/Test1”,工作项ID=3,},
新工作项{Path=“Module/Feature1/SubFeature2/Test2”,工作项ID=4,},
新工作项{Path=“Module/Feature2/SubFeature1/Test1”,工作项ID=5,},
新工作项{Path=“Module/Feature2/SubFeature1/Test2”,工作项ID=6,},
};
//在测试用例中循环。。。
foreach(tfsTestCases中的var testCase)
{
//从每个工作项的树的根开始。
TreeNode lastNode=tv.Nodes[0];
//循环遍历路径的每个部分并创建一个新节点。
//在循环中使用我们每次刚创建的节点集合。
//这允许下一次迭代在进行时“向下走”。
foreach(testCase.Path.Split('/')中的变量部分)
lastNode=AddTreeNode(lastNode.Nodes,零件);
//在循环中的最后一个节点上设置标记,这是一个具有实际测试用例的节点。
//您可以引用“tv.SelectedNode”的标记属性来访问工作项。如果标记为null,则它不是测试用例。
Tag=testCase;
lastNode.ToolTipText=testCase.WorkItemId.ToString();//为此演示设置。
}
//显示树。
tv.Dump();
}
TreeNode AddTreeNode(TreeNodeCollection节点,字符串路径)
{
//尝试在集合中查找与指定路径匹配的节点。
var node=nodes.Cast().Where(node=>node.Text==path.SingleOrDefault();
//如果找不到,创建它并将其添加到我们刚才搜索的节点集合中。
if(node==null)
{
节点=新树节点(路径);
添加(父节点);
}
//我们以后需要这个,所以把它传回去。
返回节点;
}
类工作项
{
公共字符串路径{get;set;}
公共Int32工作项ID{get;set;}
//等等。
}