简体   繁体   English

WPF TabControl选项卡更改未刷新

[英]WPF TabControl tab changes not refreshed

I have a WPF TabControl with two TabItems . 我有一个带有两个TabItemsWPF TabControl I am trying to change the selected tab on code behind on a Button click event and execute some other code. 我试图更改Button单击事件后面的代码上的选定选项卡,并执行其他代码。 In this example: 在此示例中:

private void Button_Click(object sender, RoutedEventArgs e)
{
    ConvertDataTabControl.SelectedIndex = 1;
    System.Threading.Thread.Sleep(2000);
    ...
}

I would expect the UI to refresh and move from Tab 0 to Tab 1 and only then execute the Sleep method, but the UI is refreshed only after Button_Click finishes execution. 我希望UI刷新并从Tab 0移到Tab 1 ,然后才执行Sleep方法,但是仅在Button_Click完成执行后才刷新UI。 I tried calling InvalidateVisual , but it does not work. 我尝试调用InvalidateVisual ,但是它不起作用。

Is there a way to force the UI to refresh before executing Sleep ? 有没有办法在执行Sleep之前强制UI刷新?

Your code runs on the UI thread by default, so nothing else can be executed on the UI thread (such as updating the layout) until the thread finishes executing. 默认情况下,您的代码在UI线程上运行,因此在该线程完成执行之前,无法在UI线程上执行任何其他操作(例如更新布局)。

There are many ways of releasing control of the UI thread before the code finishes executing, but I find the simplest is to use a Task from the Task Parallel Library which can be used to run code on a separate thread. 在代码完成执行之前,有很多方法可以释放对UI线程的控制,但是我发现最简单的方法是使用Task Parallel Library中Task ,该任务可用于在单独的线程上运行代码。

For example, 例如,

Task.Factory.StartNew(() =>
{
    Thread.Sleep(2000);

    // Other code here
});

It should be noted that UI objects can only be modified on the UI thread, so if your "other code here" updates a UI object, you'll probably want to use the Dispatcher to execute code on the UI thread, like this: 应该注意的是,UI对象只能在UI线程上进行修改,因此,如果“此处的其他代码”更新了UI对象,则可能要使用Dispatcher在UI线程上执行代码,如下所示:

Dispatcher.BeginInvoke(() =>
{
    // Code to update the UI
});

try 尝试

Dispatcher.BeginInvoke(()=>
{
    ConvertDataTabControl.SelectedIndex = 1;
});

The problem is you are doing your work (sleep) on the UI thread. 问题是您正在UI线程上进行工作(睡眠)。 You can use a task/backgroundworker/etc to do the work in an other thread and then do set the ui changes back to the UI thread: 您可以使用task / backgroundworker / etc在其他线程中进行工作,然后将ui更改设置回UI线程:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Dispatcher callback = Dispatcher.CurrentDispatcher;
    ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
    {
         //Do some work
         System.Threading.Thread.Sleep(2000);

         //callbackk to ui thread to do ui work. You can also use BeginInvoke...
         callback.Invoke(new Action(() => {ConvertDataTabControl.SelectedIndex = 1;}));

         //Do some more work
         System.Threading.Thread.Sleep(2000);
         ...
    }
}

It is just a example to get the idea. 这只是一个了解想法的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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