且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WPF元素事件处理程序中的UI更新

更新时间:2023-01-25 23:08:51

使用 Dispatcher.BeginInvoke 你仍在使用UI线程 LongTimeMethod()。如果这不是必需的(即它正在做某种后台处理),我建议使用TPL在后台线程上运行:

  private void ButtonClick_EventHandler(object sender,RoutedEventArgs e)
{
Label.Visibility = Visibility.Visible;
TextBox.Text =处理...;

Task.Factory.StartNew(()=> LongTimeMethod())
.ContinueWith(t =>
{
Dispatcher.BeginInvoke((Action) delegate()
{
TextBox.Text =Done!;
});
});

}

使用这种方法,长时间运行的方法在背景线程(所以UI线程将可以***地保持渲染,并且应用程序不会被冻结),并且您可以做任何改变UI(例如更新文本框文本)的任何事情在UI 调度程序当后台任务完成


There is a problem with UI update in WPF.

I have such code:

    private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
    {
        Label.Visibility = Visibility.Visible;
        TextBox.Text = "Processing...";

        LongTimeMethod(); //some long operation
    }

The problem is that until LongTimeMethod ends (that is event handler ends), Label.Visibility and TextBox.Text will not be changed.

I solved it like this so far:

    private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
    {
        Label.Visibility = Visibility.Visible;
        TextBox.Text = "Processing...";

        Dispatcher.BeginInvoke(new Action(LongTimeMethod), 
            DispatcherPriority.Background);
    }

Is there any other solution without using dispatcher invocation? Calling this.UpdateLayout() doesn't help.

With Dispatcher.BeginInvoke you are still using the UI thread for LongTimeMethod(). If this is not required (i.e. it is doing some kind of background processing) I would suggest using the TPL to run it on a background thread:

private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
{
    Label.Visibility = Visibility.Visible;
    TextBox.Text = "Processing...";

    Task.Factory.StartNew(() => LongTimeMethod())
        .ContinueWith(t =>
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                TextBox.Text = "Done!";
            });
        });

}

With this method, the long running method is processed on a background thread (so the UI thread will be free to keep rendering and the app won't freeze up) and you can do anything that does alter the UI (such as updating the textbox text) on the UI Dispatcher when the background task completes