简体   繁体   English

只要按下按钮,在C#WPF应用程序中是否有可能做某事?

[英]Is in C# WPF apps a possibility to do something as long as a button is pressed?

I'm pretty new to C# and WPF, so please forgive me if my question maybe stupid. 我对C#和WPF还是很陌生,所以如果我的问题可能很愚蠢,请原谅我。 I come from the C++ world 我来自C ++世界

I have an application that has a button, as long as I press the button I want to record a sounde from the microphone and when I release the button then the recording should stop. 我有一个带有按钮的应用程序,只要按下按钮,我就想录制麦克风的声音,当我松开按钮时,录制应停止。 Just like the voice message in WhatsApps. 就像WhatsApps中的语音消息一样。 I added the events PreviewMouseDown="ButtonLiveDown" and PreviewMouseUp="ButtonLiveUp" to my button and I can see that they are fired: 我将事件PreviewMouseDown =“ ButtonLiveDown”和PreviewMouseUp =“ ButtonLiveUp”添加到我的按钮中,可以看到它们被触发了:

My main class: 我的主班:

    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();
    }

and my Live Class: 和我的现场课程:

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();

    }
}

But this doesn't work, as long as I press the button down it seems that it stops working till I release the button. 但这是行不通的,只要我按下按钮似乎就停止了,直到我松开按钮。 From C++ I know this, as long as I press the button the system is busy with the pressed Event and can't continue to work. 从C ++我知道这一点,只要按下按钮,系统就会忙于按下的事件,并且无法继续工作。 Is it the same with C# & WPF? C#和WPF是否相同? If yes, is there any other way to handle my feature wish? 如果是,还有其他方法可以处理我的功能愿望吗?

If I understand your question, then yes, you will have to deal with UI blocking in this case. 如果我理解您的问题,那么可以,在这种情况下,您将不得不处理UI阻塞。 Use a background worker to kick the event on mouse down and background worker cancellation on mouse up. 使用后台工作者在按下鼠标时触发事件,并在鼠标按下时取消事件。 Example below shows with mouseup and mouse down event handelers as oppossed to the previewmouse up and down 下面的示例显示了mouseup和mouse down事件处理程序与上,下预览鼠标相反

Updated Example to help with understanding 更新了示例以帮助理解

XAML BUTTON: 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 behind showing background worker kicking and holding the process: 显示后台工作人员踢并按住该过程的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();
    }

}

Updated AudioLive to add property isRecording to use in our background worker: 更新了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;

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM