0

I'm working on a program for my dissertation that hopefully, when finished will enable you to sort music files using the tag data. At the moment I have a wpf tree view that I want to display a list of all the music the program has found sorted by Artist>Album>Title. I have a list of tag files collected using taglib# that I can use to create TreeViewItems for each track and can then add them to the TreeView. The problem is that I cant seem to avoid adding duplicates of artists/albums instead of adding the track as a child of the already added artist/album. I have been trying to use foreach to iterate through the items and if the header(artist name) matches the header of the new artist to be added, then move onto the album instead and add that as a child of the current item, then do the same check for albums and move on to the track title and so forth. I have been having little joy though as even if the headers match exactly they always seem to return as non-matching and thus a dupliacte artist is added.

I'm totally new to using TreeViews so I'm not sure I'm going about this in the best way, or if its just a flaw in my logic or whatever so any help would be greatly appreciated.

Attatched is the code i'm using to create and check the items.

    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);
        }

    }

The functions that create the 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;
    }

And the code for adding to the TreeView/Checking for duplicates

        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;
        }
    }

Sorry, this is a bit of a lengthy one but again, any help would be greatly appreciated :) Thanks

Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79
Jonathan
  • 1
  • 2
  • 2

1 Answers1

1

This seems like a messy and error prone approach to me, what you try to do sounds like it would be best handled by CollectionViews, which allow you to group your items without manually creating all the necessary parent containers. In WPF you should only deal with the UIElements to a minimum extent in code, most of the things can be handled via templating in XAML. So you could bind all your TreeViewItems to CollectionViews, each grouping by another property.

H.B.
  • 166,899
  • 29
  • 327
  • 400
  • Agree. The problem with using the treeview+items directly in WPF is that it gets messy real fast. It would be easier to do all of your data structures in another way, then use item templates and heirarchical data templates to get the tree view as a view. – John Gardner Jul 11 '11 at 23:50