I made an mp3 player in C#. If I select the songs at once, they automatically play one after the other, but when it comes to a song I added later, I get a "System.IndexOutOfRangeException" error. When I add music later, I want the song to play automatically one after the other, how can I do that?
string[] yol, dosya;
private void Btn_Muzik_Ekle_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
if (ofd.ShowDialog()==System.Windows.Forms.DialogResult.OK)
{
dosya = ofd.SafeFileNames;
yol = ofd.FileNames;
for (int x = 0; x < dosya.Length; x )
{
Lb_Muzik_Listesi.Items.Add(dosya[x]);
}
}
}
private void Lb_Muzik_Listesi_SelectedIndexChanged(object sender, EventArgs e)
{
OynatmaEkranı.URL = yol[Lb_Muzik_Listesi.SelectedIndex]; //This Is Where I Got The Error
OynatmaEkranı.Ctlcontrols.play();
try
{
var file = TagLib.File.Create(yol[Lb_Muzik_Listesi.SelectedIndex]);
var bin = (byte[])(file.Tag.Pictures[0].Data.Data);
Pb_Muzik_Kapak.Image = Image.FromStream(new MemoryStream(bin));
}
catch
{
}
}
private void Zamanlayıcı_Tick(object sender, EventArgs e) //Timer
{
if (OynatmaEkranı.playState==WMPLib.WMPPlayState.wmppsPlaying)
{
Pb_Muzik.Maximum=(int)OynatmaEkranı.Ctlcontrols.currentItem.duration;
Pb_Muzik.Value = (int)OynatmaEkranı.Ctlcontrols.currentPosition;
try
{
Lbl_Muzik_Sure.Text = OynatmaEkranı.Ctlcontrols.currentPositionString;
Lbl_Muzik_Bitis.Text = OynatmaEkranı.Ctlcontrols.currentItem.durationString.ToString();
}
catch
{
}
}
if (Pb_Muzik.Value==Pb_Muzik.Maximum)
{
if (Lb_Muzik_Listesi.SelectedIndex<Lb_Muzik_Listesi.Items.Count-1)
{
Lb_Muzik_Listesi.SelectedIndex = Lb_Muzik_Listesi.SelectedIndex 1;
}
}
}
CodePudding user response:
You can avoid this problem managing your data in the ListBox. Create a class with your required info (the file and the name):
public class MuzikItem
{
public MuzikItem(string file)
{
this.Text = System.IO.Path.GetFileNameWithoutExtension(file);
this.Url = file;
}
public string Text { get; set; }
public string Url { get; set; }
public override string ToString()
{
// This is the text to show in ListBox
return this.Text;
}
}
Add items to the ListBox using this class:
foreach (var file in ofd.FileNames)
{
var item = new MuzikItem(file);
Lb_Muzik_Listesi.Items.Add(item);
}
And use it:
var item = Lb_Muzik_Listesi.SelectedItem as MuzikItem;
if (item != null)
{
OynatmaEkranı.URL = item.Url;
OynatmaEkranı.Ctlcontrols.play();
try
{
var file = TagLib.File.Create(item.Url);
var bin = (byte[])file.Tag.Pictures[0].Data.Data;
Pb_Muzik_Kapak.Image = Image.FromStream(new MemoryStream(bin));
}
catch
{
}
}
You try to get the selected item as a MuzikItem (all your items are of this class so this return null only when no item is selected) and with this, you have the Url.
UPDATE
I like manage this things with events. In your Ticks methods:
if (Pb_Muzik.Value == Pb_Muzik.Maximum)
{
OnSongFinished();
}
And create a method to manage this event:
private void OnSongFinished()
{
if (Lb_Muzik_Listesi.SelectedIndex < Lb_Muzik_Listesi.Items.Count - 1)
{
Lb_Muzik_Listesi.SelectedIndex = Lb_Muzik_Listesi.SelectedIndex 1;
}
else
{
// Stop the player
OynatmaEkrani.Ctlcontrols.stop();
}
}