[英]WPF TabControl tab changes not refreshed
I have a WPF TabControl
with two TabItems
. 我有一个带有两个TabItems
的WPF 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.