动态反映WPF应用程序中的更改

本文关键字:应用程序 WPF 动态 | 更新日期: 2023-09-27 18:01:09

我正在运行一个WPF应用程序,并想做这样的事情:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        TextBox textBox = new TextBox();
        mainGrid.Children.Add(textBox);
        textBox.Text = "one";
        Thread.Sleep(1000);
        textBox.Text = "two";
        Thread.Sleep(1000);
        textBox.Text = "three";
        Thread.Sleep(1000);
        textBox.Text = "four";
    }
}

在所有这些处理完成之前,显示器不会加载,因此我有一个空白的、无响应的应用程序,直到3秒钟,在运行上述代码后,还有一个带有单词"四"的文本框。

我看了一眼BackgroundWorker课程,并尝试了这个:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // Set up background worker object & hook up handlers
        BackgroundWorker backgroundWorker;
        backgroundWorker = new BackgroundWorker();
        backgroundWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
        backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
        backgroundWorker.RunWorkerAsync();
    }
    private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
        {
            TextBox textBox = new TextBox();
            mainGrid.Children.Add(textBox);
            textBox.Text = "one";
            Thread.Sleep(1000);
            textBox.Text = "two";
            Thread.Sleep(1000);
            textBox.Text = "three";
            Thread.Sleep(1000);
            textBox.Text = "four";
        }));
    }
    private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Debug.WriteLine("done");
    }

还是一样的行为。我想在后台/不同的线程中运行一些任务,这些任务将在执行过程中对UI元素进行更改,我希望这些更改立即反映在显示中。

动态反映WPF应用程序中的更改

考虑使用asyncawait

private async void Window_Loaded(object sender, RoutedEventArgs e)
{
    TextBox textBox = new TextBox();
    mainGrid.Children.Add(textBox);
    textBox.Text = "one";
    await Task.Delay(1000);
    textBox.Text = "two";
    await Task.Delay(1000);
    textBox.Text = "three";
    await Task.Delay(1000);
    textBox.Text = "four";
}

这是关于这个主题的一个相当不错的教程。

我同意前面的海报,但如果你想使用后台工作者,请考虑看一下本教程:http://www.wpf-tutorial.com/misc/multi-threading-with-the-backgroundworker/

[…]被称为DoWork,一般规则是您不能从该事件中触摸UI中的任何内容。相反,您调用ReportProgress((方法,该方法进而引发ProgressChanged事件,您可以从中更新UI。完成后,将结果分配给工作者,然后引发RunWorkerCompleted事件。

基本上,UI需要在一个线程上运行。否则你就失去了分数。

async await可能是最好的答案,但在这种情况下也可以使用计时器。

    System.Timers.Timer t;
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        t = new System.Timers.Timer();
        t.Elapsed += t_Elapsed;
        t.Interval = 1000;
        t.Start();
    }
    int tickCount = 0;
    void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        tickCount++;
        switch (tickCount)
        {
            case 1: textBox.Text = "one"; break;
            case 2: textBox.Text = "two"; break;
            case 3: textBox.Text = "three"; break;
            case 4: textBox.Text = "four"; break;
            case 5: t.Stop(); break;
        }
    }