Есть ли в приложениях C # WPF возможность что-то делать, пока нажата кнопка? - PullRequest
0 голосов
/ 11 декабря 2018

Я довольно новичок в C # и WPF, поэтому, пожалуйста, прости меня, если мой вопрос может быть глупым.Я из мира C ++

У меня есть приложение, в котором есть кнопка. Пока я нажимаю кнопку, я хочу записать звук с микрофона, и когда я отпускаю кнопку, запись должна остановиться.Так же, как голосовое сообщение в WhatsApps.Я добавил события PreviewMouseDown = "ButtonLiveDown" и PreviewMouseUp = "ButtonLiveUp" к своей кнопке и вижу, что они запускаются:

Мой основной класс:

    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?Если да, есть ли другой способ справиться с моим пожеланием?

1 Ответ

0 голосов
/ 11 декабря 2018

Если я понимаю ваш вопрос, тогда да, вам придется иметь дело с блокировкой пользовательского интерфейса в этом случае.Используйте фонового работника, чтобы выкинуть событие мышью вниз, а фонового работника - мышью вверх.В приведенном ниже примере показаны обработчики событий 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;

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...