简体   繁体   中英

Reflect changes in WPF application dynamically

I' running a WPF application and want to do something like this:

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

The display doesn't load until all of this processing is complete hence I have a blank, unresponsive application till 3 seconds and a textbox with the word four after running the above code.

I had a look at the BackgroundWorker class and tried this:

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

Still the same behaviour. I want to run some tasks in the background/ in different threads which will make changes to the UI elements along execution and I want these changes to be reflected in the display immediately.

Consider using async and await instead:

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

Here is a rather nice tutorial on the subject.

I agree with the previous posters however if you'd like to use background worker consider taking a look at this tutorial: http://www.wpf-tutorial.com/misc/multi-threading-with-the-backgroundworker/

[...] is called DoWork and the general rule is that you can't touch anything in the UI from this event. Instead, you call the ReportProgress() method, which in turn raises the ProgressChanged event, from where you can update the UI. Once you're done, you assign a result to the worker and then the RunWorkerCompleted event is raised.

Basically the UI needs to run on one thread. Otherwise you lose the point.

async await is likely the best answer, however a timer can be used in this situation as well.

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

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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