在C#WPF应用程序中,只要按下一个按钮,就有可能做一些事情吗



我对C#和WPF还很陌生,所以如果我的问题可能很愚蠢,请原谅我。我来自C++世界

我有一个有按钮的应用程序,只要我按下按钮,我就想从麦克风录制声音,当我松开按钮时,录制就会停止。就像WhatsApp中的语音消息一样。我在我的按钮上添加了事件PreviewMouseDown="ButtonLiveDown"和PreviewMousUp="ButtonLive Up",我可以看到它们被触发了:

我的主要课程:

m_MyLive = new AudioLive();
m_MyLive.Init(this);
private void ButtonLiveDown(object sender, MouseButtonEventArgs e)
{
m_MyLive.StartLive();
}
private void ButtonLiveUp(object sender, MouseButtonEventArgs e)
{
m_MyLive.EndLive();
}

和我的直播课:

class AudioLive
{
private MainWindow m_mainWindow;
private WaveIn m_Recorder;
private BufferedWaveProvider m_BufferedWaveProvider;
private SavingWaveProvider m_SavingWaveProvider;
private WaveOut m_Player;

public void Dispose()
{
Dispose(true);
}

protected virtual void Dispose(bool disposing)
{
if (m_Recorder != null)
{
m_Recorder.Dispose();
}

m_Recorder = null;
if (m_SavingWaveProvider != null)
{
m_SavingWaveProvider.Dispose();
}

m_SavingWaveProvider = null;
}
private void RecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
{
m_BufferedWaveProvider.AddSamples(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);
}

public bool Init(MainWindow mainWindow)
{
m_mainWindow = mainWindow;
m_Recorder = new WaveIn();
m_Recorder.DataAvailable += RecorderOnDataAvailable;
// set up our signal chain
m_BufferedWaveProvider = new BufferedWaveProvider(m_Recorder.WaveFormat);
m_SavingWaveProvider = new SavingWaveProvider(m_BufferedWaveProvider, "live.wav");
// set up playback
m_Player = new WaveOut();
m_Player.Init(m_SavingWaveProvider);

return true;
}

public void SetMicVolume(int nVol)
{
....
}

public void StartLive()
{

SetMicVolume(100);
// begin playback & record
m_Player.Play();
m_Recorder.StartRecording();

}
public void EndLive()
{

// stop recording
m_Recorder.StopRecording();
// stop playback
m_Player.Stop();
}
}

但这不起作用,只要我按下按钮,它似乎就停止工作,直到我松开按钮。从C++我知道,只要我按下按钮,系统就会忙于按下的事件,无法继续工作。它和C#一样吗;WPF?如果是,有没有其他方法来处理我的功能愿望?

如果我理解你的问题,那么是的,在这种情况下,你将不得不处理UI阻塞。使用后台工作程序在鼠标放下时启动事件,在鼠标抬起时取消后台工作程序。下面的示例显示了鼠标向上和向下事件切换器,与预览鼠标向上或向下相反

更新示例以帮助理解

XAML按钮:

<Button x:Name="RecordBtn" Content="Button" HorizontalAlignment="Left" Margin="363,199,0,0" VerticalAlignment="Top" Width="75" MouseDown="Button_MouseDown" MouseUp="Button_MouseUp"/>

xaml代码背后显示后台工作人员踢和持有过程:

public partial class MainWindow : Window
{
private readonly BackgroundWorker worker = new BackgroundWorker();
AudioLive m_MyLive = new AudioLive();
Stopwatch stopWatch = new Stopwatch();

public MainWindow()
{
InitializeComponent();
AddHandler(FrameworkElement.MouseDownEvent, new MouseButtonEventHandler(Button_MouseDown), true);
AddHandler(FrameworkElement.MouseUpEvent, new MouseButtonEventHandler(Button_MouseUp), true);
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.WorkerSupportsCancellation = true;
m_MyLive.Init(this);
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
if (!m_MyLive.IsRecordinginProgress() && !worker.CancellationPending)
{
m_MyLive.StartLive();
stopWatch.Reset();
stopWatch.Start();
}
while (m_MyLive.IsRecordinginProgress() && !worker.CancellationPending)
{
this.Dispatcher.Invoke(() =>
{
updateLabel(String.Format("{0:0.#}", TimeSpan.FromMilliseconds(stopWatch.ElapsedMilliseconds).TotalSeconds) + " seconds");
});
}
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
m_MyLive.EndLive();
stopWatch.Stop();
updateLabel(String.Format("{0:0.#}", TimeSpan.FromMilliseconds(stopWatch.ElapsedMilliseconds).TotalSeconds) + " seconds");
}
private void updateLabel(string text)
{
RecordBtn.Content = text;
}

private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
worker.RunWorkerAsync();
}
private void Button_MouseUp(object sender, MouseButtonEventArgs e)
{
worker.CancelAsync();
}
}

更新AudioLive以添加属性isRecording以用于我们的后台工作人员:

public class AudioLive
{
private MainWindow m_mainWindow;
private WaveIn m_Recorder;
private BufferedWaveProvider m_BufferedWaveProvider;
private SavingWaveProvider m_SavingWaveProvider;
private WaveOut m_Player;
private bool isRecording { get; set; }

public bool IsRecordinginProgress()
{
return isRecording;
}
public void Dispose()
{
Dispose(true);
}

protected virtual void Dispose(bool disposing)
{
if (m_Recorder != null)
{
m_Recorder.Dispose();
}

m_Recorder = null;
if (m_SavingWaveProvider != null)
{
m_SavingWaveProvider.Dispose();
}

m_SavingWaveProvider = null;
}
private void RecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
{
m_BufferedWaveProvider.AddSamples(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);
}

public bool Init(MainWindow mainWindow)
{
m_mainWindow = mainWindow;
m_Recorder = new WaveIn();
m_Recorder.DataAvailable += RecorderOnDataAvailable;
// set up our signal chain
m_BufferedWaveProvider = new BufferedWaveProvider(m_Recorder.WaveFormat);
m_SavingWaveProvider = new SavingWaveProvider(m_BufferedWaveProvider, "live.wav");
// set up playback
m_Player = new WaveOut();
m_Player.Init(m_SavingWaveProvider);

return true;
}

public void SetMicVolume(int nVol)
{
}

public void StartLive()
{

SetMicVolume(100);
// begin playback & record
m_Player.Play();
m_Recorder.StartRecording();
isRecording = true;

}
public void EndLive()
{

// stop recording
m_Recorder.StopRecording();
// stop playback
m_Player.Stop();
isRecording = false;
}
}

相关内容

最新更新