2016-11-30 160 views
2

我正在玩一些C#,我正在编写一个钢琴应用程序。遍历列表C#

每当用户点击钢琴音符时,我将声音(.wav)的位置存储到列表中......以下是button1_MouseDown方法中的一些代码。

if (e.Button == MouseButtons.Left) 
    { 
     SoundPlayer sp = new SoundPlayer(); 
     string musName = Convert.ToString(mk.pitch); 
     string loc = @"D:\OneDrive\Year 2 Semester 1\OOP\Notes-Sound files\Notes-Sound files\mapped\" + musName + ".wav"; 
     sp.SoundLocation = loc; 
     sp.Play(); 
     music.Add(loc); 
    } 

现在,我想遍历循环播放所有点击的键一次。我这样做如下(当用户点击播放按钮)

int k = 0; 
for (k = 1; k < music.Count; k++) 
{ 
    SoundPlayer sp = new SoundPlayer(); 
    sp.SoundLocation = music[k]; 
    sp.Play(); 
} 

的事情是,每当单击播放按钮按下唯一的最后一个音符是played.However,当我调试,不知何故,所有音符被播放。有任何想法吗?

+0

嗨,我认为你必须等待每一个音符演奏下一个 –

+0

我还假设哟不需额外需要每一个迭代中intialize一个新玩家以前玩过,但外循环。 – HimBromBeere

回答

5

根据MSDN,这是Play方法的描述:

播放使用一个新的线程.wav文件,如果它没有被加载首先加载.wav文件。

所以每当你调用Play,这是异步运行,你的循环将继续完成当前一个之前执行播放下一个wav文件。当你进行调试时,你可能在等待循环。

相反,尝试使用PlaySync播放声音同步

PS。此外,您可能要考虑使用的SoundPlayer的情况下,在你的列表,而不是文件名,以避免产生新的实例每次播放的wav文件时间:

List<SoundPlayer> music = new List<SoundPlayer>(); 
//... 

//In your first loop, you would add the SoundPlayer object 
music.Add(sp); 

//.. 
//Then when you're playing back: 
for (int k = 0; k < music.Count; k++) 
{ 
    music[k].PlaySync(); 
} 

注意的是,在for循环的指数应该在开始0以及

+0

这应该是公认的答案! +1 – nik0lias

+0

@KMoussa 我应该在哪里放置 'var music = new List ();' – Axel

+0

@AxelAzzopardi取代您当前声明的'strings'音乐列表/数组' – KMoussa

0

你的主要问题是,票据全部发挥,但随后的音符真正开始打第一个完成之前。因此你只听到最后一个。

使用PlaySync,它会同步播放声音,如果您出于某种原因必须遍历List<>并说,请在播放前检查每个项目(至少如果您将SoundPlayer派生到另一个类,以便它实际上有东西要检查),您可以使用支票进行PlaySync调用。

SoundPlayer sp = new SoundPlayer(); 

foreach(var note in music) 
{ 
    sp.SoundLocation = note; 
    bool everythingIsFine = false; 

    // Logic for everythingIsFine; 

    if(everythingIsFine){ 
     sp.PlaySync(); 
    } 
}