0

我有WPF TabControl两个TabItems。我正在尝试更改Button单击事件后面代码上的选定选项卡并执行一些其他代码。在这个例子中:

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

我希望 UI 刷新并从Tab 0to移动,Tab 1然后才执行 Sleep 方法,但 UI 仅在Button_Click完成执行后才会刷新。我试过打电话InvalidateVisual,但它不起作用。

有没有办法在执行之前强制 UI 刷新Sleep

4

3 回答 3

2

默认情况下,您的代码在 UI 线程上运行,因此在线程完成执行之前,无法在 UI 线程上执行任何其他操作(例如更新布局)。

有很多方法可以在代码完成执行之前释放对 UI 线程的控制,但我发现最简单的方法是使用任务并行库Task中的一个,它可用于在单独的线程上运行代码。

例如,

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

    // Other code here
});

需要注意的是,UI 对象只能在 UI 线程上修改,因此如果您的“此处的其他代码”更新了 UI 对象,您可能希望使用Dispatcher在 UI 线程上执行代码,如下所示:

Dispatcher.BeginInvoke(() =>
{
    // Code to update the UI
});
于 2013-03-21T14:56:16.900 回答
1

尝试

Dispatcher.BeginInvoke(()=>
{
    ConvertDataTabControl.SelectedIndex = 1;
});
于 2013-03-21T13:45:07.980 回答
0

问题是你在 UI 线程上做你的工作(睡眠)。您可以使用任务/后台工作人员/等在其他线程中完成工作,然后将 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);
         ...
    }
}

这只是一个例子。

于 2013-07-10T09:36:45.510 回答