首页 文章

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

提问于
浏览
0

我正在运行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秒,并且在运行上述代码后,文本框中包含单词4 .

我看了一下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元素进行更改,并且我希望这些更改立即反映在显示中 .

3 回答

  • 0

    考虑使用 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";
    }
    

    关于这个问题,这是一个相当不错的tutorial .

  • 4

    我同意以前的海报,但是如果你想使用后台工作人员考虑看看这个教程:http://www.wpf-tutorial.com/misc/multi-threading-with-the-backgroundworker/

    [...]称为DoWork,一般规则是您不能通过此事件触摸UI中的任何内容 . 相反,您调用ReportProgress()方法,该方法又会引发ProgressChanged事件,您可以从中更新UI . 完成后,将结果分配给worker,然后引发RunWorkerCompleted事件 .

    基本上UI需要在一个线程上运行 . 否则你就失去了重点 .

  • 1

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

相关问题