我有两个WPF TabControl
的{{1}}。我正在尝试更改TabItems
点击事件背后代码的选定选项卡,并执行其他一些代码。在这个例子中:
Button
我希望UI能够刷新并从private void Button_Click(object sender, RoutedEventArgs e)
{
ConvertDataTabControl.SelectedIndex = 1;
System.Threading.Thread.Sleep(2000);
...
}
移动到Tab 0
,然后才执行Sleep方法,但只有在Tab 1
完成执行后才会刷新UI。我尝试调用Button_Click
,但它不起作用。
有没有办法在执行InvalidateVisual
之前强制UI刷新?
答案 0 :(得分:2)
默认情况下,您的代码在UI线程上运行,因此在线程完成执行之前,不能在UI线程上执行任何其他操作(例如更新布局)。
在代码完成执行之前有很多方法可以释放对UI线程的控制,但我发现最简单的方法是使用Task Parallel Library中的Task
,它可以用来运行代码。单独的线程。
例如,
Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
// Other code here
});
应该注意的是UI对象只能在UI线程上修改,所以如果你的“其他代码在这里”更新UI对象,你可能会想要使用Dispatcher来执行代码。 UI线程,如下所示:
Dispatcher.BeginInvoke(() =>
{
// Code to update the UI
});
答案 1 :(得分:1)
试
Dispatcher.BeginInvoke(()=>
{
ConvertDataTabControl.SelectedIndex = 1;
});
答案 2 :(得分:0)
问题是你正在UI线程上做你的工作(睡眠)。你可以使用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);
...
}
}
这只是一个实现这个想法的例子。