[英]WPF - How to stop a TabControl changing indices in a MouseUp event?
[英]Stop SoundPlayer on mouseUp event
tl; dr版本:如何在WinForms按钮的MouseDown事件中开始播放声音,并停止在同一按钮的MouseUp事件中播放声音?
中级C#开发人员,我一直在尝试编写一个简单的Simon克隆。
我目前只能尝试在用户单击按钮时使其播放彩色按钮的声音。 (我交替使用“按钮”和“平铺”。两者均指用户将在表单上按下的彩色按钮)
我最初尝试过:
public partial class frmMain : Form
{
private SoundPlayer soundPlayer;
private void btnGreenTile_MouseDown(object sender, MouseEventArgs e)
{
soundPlayer = new SoundPlayer(Properties.Resources.greenTileSound)
soundPlayer.Play();
}
private void btnGreenTile_MouseUp(object sender, MouseEventArgs e)
{
soundPlayer.Stop();
}
}
但这并没有停止声音,因为未完成MouseDown导致MouseUp事件没有触发(如果有人按住按钮的时间超过一次简单的单击,则仍会播放大约5秒钟的声音)。
正如Luis Tellez在评论中提到的那样,SoundPlayer在新线程上播放声音...所以我不知道为什么该代码现在不起作用。
因此,我研究了多线程并尝试了以下方法:
public partial class frmMain : Form
{
private Thread soundThread = new Thread(new ParameterizedThreadStart(PlaySound));
// Create stream objects for each sound (needed to allow SoundPlayer to use Resources)
private Stream greenTileSound = Properties.Resources.greenTilePress;
private Stream redTileSound = Properties.Resources.redTilePress;
private Stream yellowTileSound = Properties.Resources.yellowTilePress;
private Stream blueTileSound = Properties.Resources.blueTilePress;
public frmMain()
{
InitializeComponent();
}
private void btnGreenTile_MouseDown(object sender, MouseEventArgs e)
{
soundThread.Start(greenTileSound);
}
private void btnGreenTile_MouseUp(object sender, MouseEventArgs e)
{
soundThread.Abort();
}
// Have to use object as parameter because ParamterizedThreadStart() only takes object arguments
private static void PlaySound(object soundToPlay)
{
SoundPlayer soundPlayer = new SoundPlayer((Stream)soundToPlay);
soundPlayer.Play();
}
}
使用上面的代码,它不会停止在MouseUp上播放声音,甚至更好的是,它会引发ThreadStateException并显示消息“线程正在运行或终止;它无法重新启动”。
您可能会说,我只是在尝试编写此代码时才了解多线程。 我必须使用ParameterizedThreadStart,因为它在线程启动时调用的方法PlaySound()需要使用与播放器按下的彩色按钮相对应的资源(.wav文件)将参数传递给soundPlayer。
然后我以为也许我应该尝试使用soundThread.Suspend()而不是soundThread.Abort(),但是Suspend已被弃用...
谁能指出我正确的方向,以使声音在MouseUp上停止播放? 我需要使用多线程吗? 我认为我的问题只能归结为逻辑,但我完全陷入困境。 感谢您提供的所有帮助! :)
附带说明一下,对于这个问题或尚未提出类似要求的问题,我感到有些惊讶(至少在Google搜索或stackExchange搜索中找不到)。
您可以在文档中看到play()方法在其他线程中运行,您可以在它之后执行其他操作,并且它应该运行,因此第一种方法的问题与您的想法有所不同。
Play方法使用新线程播放声音。 如果在.wav文件加载到内存之前调用Play,则将在回放开始之前加载.wav文件。 您可以使用LoadAsync或Load方法将.wav文件预先加载到内存中。 从流或URL成功加载.wav文件后,将来对SoundPlayer的播放方法的调用将无需重新加载.wav文件,直到声音的路径发生变化为止。 如果未指定.wav文件或加载失败,则Play方法将播放默认的提示音。
http://msdn.microsoft.com/en-us/library/system.media.soundplayer.play%28v=vs.110%29.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.