Если я понимаю ваш вопрос, тогда да, вам придется иметь дело с блокировкой пользовательского интерфейса в этом случае.Используйте фонового работника, чтобы выкинуть событие мышью вниз, а фонового работника - мышью вверх.В приведенном ниже примере показаны обработчики событий mouseup и mouse down, в отличие от превью мыши вверх и вниз
Обновленный пример, помогающий понять * КНОПКУ 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 codeпозади показа фонового работника, запускающего и удерживающего процесс:
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;
}
}