我正在为我的论文开发一个程序,希望完成后可以使用标签数据对音乐文件进行排序。目前我有一个wpf树视图,我想显示程序找到的所有音乐列表,按艺术家>专辑>标题排序。我有一个使用taglib#收集的标记文件列表,我可以使用它来为每个轨道创建TreeViewItems,然后将它们添加到TreeView中。问题是,我似乎无法避免添加艺术家/专辑的重复,而不是添加轨道作为已添加的艺术家/专辑的孩子。我一直在尝试使用foreach来遍历项目,如果标题(艺术家名称)与要添加的新艺术家的标题相匹配,则转移到相册并将其添加为当前项目的子项,然后执行同样检查专辑并转到曲目标题等等。我一直没有什么快乐,因为即使标题完全匹配,它们似乎总是以不匹配的形式返回,因此添加了一个双重艺术家。
我对使用TreeViews完全不熟悉所以我不确定我是以最好的方式解决这个问题,或者如果它只是我的逻辑中的一个缺陷或其他任何帮助将非常感激。
Attatched是我用来创建和检查项目的代码。
public void PopulateTreeView(TreeView searchResults)
{
foreach (TagLib.File tagFile in tagFiles)
{
TreeViewItem Artist;
TreeViewItem Album;
TreeViewItem Title;
//creating the TreeViewItems
Artist = SetArtistsName(tagFile);
Album = SetAlbumName(tagFile);
Title = SetTrackName(tagFile);
//adding them to TreeView
AddArtistToTreeView(tagFile, searchResults, Artist, Album, Title);
}
}
创建TreeViewItems的函数
private TreeViewItem SetArtistsName(TagLib.File tagFile)
{
TreeViewItem Artist = new TreeViewItem();
if (tagFile.Tag.AlbumArtists.Length == 0)
{
Artist.Header = "Unknown Artist";
return Artist;
}
else
{
Artist.Header = tagFile.Tag.AlbumArtists[0].ToString();
return Artist;
}
}
private TreeViewItem SetAlbumName(TagLib.File tagFile)
{
TreeViewItem Album = new TreeViewItem();
Album.Header = tagFile.Tag.Album;
return Album;
}
private TreeViewItem SetTrackName(TagLib.File tagFile)
{
TreeViewItem Track = new TreeViewItem();
Track.Header = tagFile.Tag.Title;
return Track;
}
添加到TreeView /检查重复项的代码
private void AddArtistToTreeView(TagLib.File tagFile, TreeView searchResults, TreeViewItem Artist, TreeViewItem Album, TreeViewItem Title)
{
if (searchResults.Items.Count == 0)
{
searchResults.Items.Add(Artist);
Artist.Items.Add(Album);
Album.Items.Add(Title);
}
else
{
artistFlag = CheckArtist(searchResults, Artist);
switch (artistFlag)
{
case 0:
searchResults.Items.Add(Artist);
if (Artist.Items.Count == 0)
{
Artist.Items.Add(Album);
Album.Items.Add(Title);
}
break;
case 1:
albumFlag = CheckAlbum(Artist, Album);
switch (albumFlag)
{
case 0:
Artist.Items.Add(Album);
if (Album.Items.Count == 0)
{
Album.Items.Add(Title);
}
break;
case 1:
trackFlag = CheckTitle(Album, Title);
break;
case 2:
break;
}
break;
case 2:
break;
}
}
}
private int CheckArtist(TreeView searchResults, TreeViewItem Artist)
{
if (searchResults.Items.Count == 0)
{
return 0;
}
else
{
foreach (TreeViewItem tvi in searchResults.Items)
{
if (tvi.Header.ToString() != Artist.Header.ToString())
{
return 0;
}
else
{
return 1;
}
}
return 2;
}
}
private int CheckAlbum(TreeViewItem Artist, TreeViewItem Album)
{
if (Artist.Items.Count == 0)
{
return 0;
}
else
{
foreach (TreeViewItem tvi in Artist.Items)
{
if (tvi.Header.ToString() != Album.Header.ToString())
{
return 0;
}
else
{
return 1;
}
}
return 2;
}
}
private int CheckTitle(TreeViewItem Album, TreeViewItem Title)
{
if (Album.Items.Count == 0)
{
return 0;
}
else
{
foreach (TreeViewItem tvi in Album.Items)
{
if (tvi.Header.ToString() != Title.Header.ToString())
{
return 0;
}
else
{
return 1;
}
}
return 2;
}
}
对不起,这是一个冗长的,但再次,任何帮助将不胜感激:)谢谢
答案 0 :(得分:1)
这对我来说似乎是一个混乱且容易出错的方法,你尝试做的事情听起来最好由CollectionViews
处理,这样你就可以group your items而无需手动创建所有必要的父母容器。在WPF中,您应该只在代码中处理UIElements,大部分内容都可以通过XAML中的templating来处理。因此,您可以bind TreeViewItems
到CollectionViews
,每个属性由另一个属性进行分组。