簡體   English   中英

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

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

我對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是否相同? 如果是,還有其他方法可以處理我的功能願望嗎?

如果我理解您的問題,那么可以,在這種情況下,您將不得不處理UI阻塞。 使用后台工作者在按下鼠標時觸發事件,並在鼠標按下時取消事件。 下面的示例顯示了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代碼:

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;

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM