我有一个包含许多文件的列表。我想在树结构而不是平面列表中显示此列表。 像这样:
2001
- 2001-01
-2001-01-01
-File 1
-File 2
-File 3
-File 4
-2001-01-02
-File 5
-File 6
-File 7
-File 8
-2001-01-03
- etc
-2001-01-03
etc...
我发现了类似的东西,但不知道如何将它应用于我的设置。 How to efficiently build a tree from a flat structure?
文件有一个DateTime字段,我在那里得到日期。
我可以将所有文件分组到同一日期吗?
编辑: 现在列表显示如下
2001-01-01 - File 1
2001-01-01 - File 2
2001-01-01 - File 3
2001-01-01 - File 4
2001-01-02 - File 5
2001-01-02 - File 6
2001-01-02 - File 7
etc
答案 0 :(得分:2)
我假设你有一个名为Files of FileInfo-objects的排序数组。然后你可以像下面一样迭代它:
foreach (FileInfo fi in Files)
{
AddNode(fi);
}
AddNode成员将节点添加到树中:
private void AddNode(FileInfo F)
{
// Create the node labels.
string y = String.Format("{0:yyyy}", F.LastWriteTime);
string ym = String.Format("{0:yyyy-MM}", F.LastWriteTime);
string ymd = String.Format("{0:yyyy-MM-dd}", F.LastWriteTime);
TreeNode[] tnY = null;
TreeNode[] tnYM = null;
TreeNode[] tnYMD = null;
// Find existing tree nodes for the file we are working on.
tnY = treeView1.Nodes.Find(y, false);
if (tnY.Length == 1)
{
tnYM = tnY[0].Nodes.Find(ym, false);
if (tnYM.Length == 1)
{
tnYMD = tnYM[0].Nodes.Find(ymd, false);
}
}
// Create the missing nodes.
if (tnY.Length == 0)
{
tnY = new TreeNode[1];
tnY[0] = treeView1.Nodes.Add(y, y);
}
if (tnYM == null || tnYM.Length == 0)
{
tnYM = new TreeNode[1];
tnYM[0] = tnY[0].Nodes.Add(ym, ym);
}
if (tnYMD == null || tnYMD.Length == 0)
{
tnYMD = new TreeNode[1];
tnYMD[0] = tnYM[0].Nodes.Add(ymd, ymd);
}
// And finally, add the node with the file name.
tnYMD[0].Nodes.Add(F.Name);
}
答案 1 :(得分:1)
好的,这只是一个非常简单的实现,但它可以解决问题:)
List<string> files = new List<string>()
{
{"2001-01-01 - File 1"},
{"2001-01-01 - File 2"},
{"2001-01-02 - File 1"},
{"2001-01-03 - File 1"}
};
TreeView tv = new TreeView();
foreach(string file in files)
{
string y = file.Substring(0, 4);
string ym = file.Substring(0, 7);
string ymd = file.Substring(0, 10);
string fn = file.Substring(13);
TreeNode Node = tv.Nodes[y] ?? tv.Nodes.Add(y,y);
Node = Node.Nodes[ym] ?? Node.Nodes.Add(ym,ym);
Node = Node.Nodes[ymd] ?? Node.Nodes.Add(ymd,ymd);
Node.Nodes.Add(fn);
}
编辑:所以,我并没有真正注意到使用DateTime的信息。为此,我现在使用一个填充了具有DateTime和字符串文件名的类的List:
List<fi> files = new List<fi>()
{
new fi(new DateTime(2001, 1, 1), "File 1"),
new fi(new DateTime(2001, 1, 1), "File 2"),
new fi(new DateTime(2001, 1, 3), "File 3"),
new fi(new DateTime(2001, 1, 1), "File 4"),
new fi(new DateTime(2001, 1, 2), "File 5"),
new fi(new DateTime(2001, 1, 2), "File 6"),
new fi(new DateTime(2001, 1, 2), "File 7")
};
TreeView tv = new TreeView();
var orderedfiles = from file in files orderby file.date ascending select file;
foreach(fi file in orderedfiles)
{
TreeNode Node = tv.Nodes[file.date.Year.ToString()] ?? tv.Nodes.Add(file.date.Year.ToString(), file.date.Year.ToString());
Node = Node.Nodes[file.date.ToString("yyyy-mm")] ?? Node.Nodes.Add(file.date.ToString("yyyy-mm"), file.date.ToString("yyyy-mm"));
Node = Node.Nodes[file.date.ToString("yyyy-mm-dd")] ?? Node.Nodes.Add(file.date.ToString("yyyy-mm-dd"), file.date.ToString("yyyy-mm-dd"));
Node.Nodes.Add(file.fn);
}
答案 2 :(得分:1)
基本思路是跟踪上一年,一月和一天,以便了解是否应创建新的父节点。你没有说你想要在树视图中显示它,所以我假设你想要它在标准文本或HTML中。使其成为树视图控件在实现中稍微复杂一些,但基本思想没有任何不同。
我将提供伪代码,而不是陷入C#实现的细节中。这将使我更容易理解这些想法,并且更容易移植到适合您的数据和输出方法所需的任何形式。
这假设文件按日期排序,最早的日期(即最旧的文件)排在第一位。
首先将前一天,月和年设置为-1:
previousYear = -1
previousMonth = -1
previousDay = -1
for each file in list
{
if (file.date.year != previousYear)
{
output file.date.year
previousYear = file.date.year
// set previousMonth to default to force a new month folder
previousMonth = -1
}
if (file.date.Month != previousMonth)
{
output file.date.month
previousMonth = file.date.month
// set previousDay to default to force a new day folder
previousDay = -1
}
if (file.date.day != previousDay)
{
output file.date.day
previousDay = file.date.day
}
// and then output the file name
output file.name
}