Question

I have this MP3 player which looks like this:

http://tinypic.com/view.php?pic=mkvzly&s=8#.U3My1_l_uEo

I can use the buttons without problem, they're working fine. The problem is coming when I want to play the songs. If i add 1 song to the listbox, doubleclick it, it is playing! Awesome? Well yea, except the fact if I add another song, the first song is still clickable and is playing, but as soon as I click on any other song than the first, it crashes.

I am getting following error:

Listbox index out of array

Heres the code which contain the error:

string[] files, paths;

private void lbplaylist_DoubleMouseClick(object sender, EventArgs e) // Start på event
{
    player.URL = paths[lbplaylist.SelectedIndex];
}

Help please. Complete code with suggestion implented:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WORKS_EKSAMENSPROJEKT
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string[] files, paths;

        private void lbplaylist_DoubleMouseClick(object sender, EventArgs e) // Start på event
        {
            if (lbplaylist.SelectedItem != null)
                player.URL = (lbplaylist.SelectedItem as Song).Path;
        }
        private void btOpenFiles_Click(object sender, EventArgs e)
        {
            OpenFileDialog open = new OpenFileDialog();
            openFileDialog1.Filter = ("MP3 Files| *.mp3|Wave Files| *.wav|WMA Files|*.wma|All Files|*.*");
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                files = openFileDialog1.SafeFileNames;
                paths = openFileDialog1.FileNames; 
                for (int i = 0; i < files.Length; i++)
                {
                    lbplaylist.Items.Add(files[i]);
                }
            }
        }
        private void btReset_Click(object sender, EventArgs e)
        {
            lbplaylist.Items.Clear();
        }
        public class Song
        {
            public string Title;
            public string Path;

            public override string ToString()
            {
                return Title;
            }

            public override int GetHashCode()
            {
                return ToString().GetHashCode();
            }

            public override bool Equals(object obj)
            {
                if (obj is Song)
                    return this.Path.Equals(((Song)obj).Path);
                else
                    return base.Equals(obj);
            }
        }
    }
}
Was it helpful?

Solution

Well, the most obvious cause of the error is that paths doesn't have the second entry. The question is why. If you add another song to the play list, you need to make sure that a new entry is also added to paths.

It might be a good idea to do the following:

  1. Create a new helper class called Song which contains the title and the path to the MP3 file. Override its ToString() method to return the song title.
  2. When adding a new song to the playlist, create a new instance of Song with the appropriate information and add that to the listbox.
  3. When an entry is double-clicked, play the file from the path of the selected Song object, not another list in your code.

That way you only have to maintain one list.

Example:

public class Song
{
    public string Title;
    public string Path;

    public override string ToString()
    {
        return Title;
    }

    public override int GetHashCode()
    {
        return ToString().GetHashCode();
    }

    public override bool Equals(object obj)
    {
        if (obj is Song)
            return this.Path.Equals(((Song)obj).Path);
        else
            return base.Equals(obj);
    }
}

Then the code for double-clicking a list item comes down to:

private void lbplaylist_DoubleMouseClick(object sender, EventArgs e) // Start på event
{
    if (lbplayList.SelectedItem != null)
        player.URL = (lbplayList.SelectedItem as Song).Path;
}

To add a new file to the playlist you can use this:

Song s = new Song() { Title = title, Path = filePath };
lbplayList.Items.Add(s);

Please note that filePath should contain the full path to an MP3 file (path + name).


To add the Song items to the playlist properly, please use this:

private void btOpenFiles_Click(object sender, EventArgs e)
{
    OpenFileDialog open = new OpenFileDialog();
    openFileDialog1.Filter = ("MP3 Files|*.mp3|Wave Files|*.wav|WMA Files|*.wma|All Files|*.*");

    if (openFileDialog1.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
    {
        foreach (string file in openFileDialog1.FileNames)
        {
            Song s = new Song() { Title = Path.GetFileNameWithoutExtension(file), Path = file };
            lbplaylist.Items.Add(s);
        }
    }
}

Also, it is now pretty obvious why you got the error in the first place! With every click to btnOpenFiles you set paths to contain only the last selected files names. So if you selected one file upon the first click and another on the second click, the list box would contain two entries, but paths would contain only the last selection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top