WPF从同一线程中的另一个窗口更新窗口的UI控件
假设我分别定义了两个名为WindowA和WindowB的窗口 WindowA有一个名为btn的按钮 WindowB有一个名为processLbl的标签 当用户单击WindowA中的按钮时,将显示WindowB并执行一些逻辑WPF从同一线程中的另一个窗口更新窗口的UI控件,wpf,multithreading,Wpf,Multithreading,假设我分别定义了两个名为WindowA和WindowB的窗口 WindowA有一个名为btn的按钮 WindowB有一个名为processLbl的标签 当用户单击WindowA中的按钮时,将显示WindowB并执行一些逻辑 WindowB windowB; private void btn_Click(object sender, RoutedEventArgs e) { windowB = new WindowB(); windowB.Owner = Application.
WindowB windowB;
private void btn_Click(object sender, RoutedEventArgs e)
{
windowB = new WindowB();
windowB.Owner = Application.Current.MainWindow;
windowB.Show();
for (int i = 0; i < 100; i++)
{
// do something
Thread.Sleep(100);
updateLabel(i);
}
windowB.Close();
}
private void updateLabel(int value)
{
windowB.processLbl.Content = value;
}
结果显示windowB,但其标签内容未更新
我想这是意料之中的,因为windowA和windowB都在同一个线程上
因此,使用Dispatcher.Invoke是没有用的
但有没有办法做到这一点,或者我必须在不同的线程上显示windowB
如果我这样做了,我如何从运行windowA的线程访问windowB的标签呢?试试下面的调度程序计时器
WindowB window;
DispatcherTimer timer = new DispatcherTimer();
private void Button_Click(object sender, RoutedEventArgs e)
{
window = new WindowB
{
Owner = Application.Current.MainWindow
};
window.Show();
timer.Tick -= Timer_Tick;
timer.Tick += Timer_Tick;
timer.Interval = new TimeSpan(0, 0, 1);
timer.Start();
}
int tickCount = 1;
private void Timer_Tick(object sender, EventArgs e)
{
if (tickCount == 100)
{
window.Close();
timer.Stop();
}
updateLabel(tickCount);
tickCount++;
}
private void updateLabel(int value)
{
window.lbl.Content = value;
}
正如clemens在评论中提到的,Thread.Sleep阻止UI线程Thread.Sleep阻止UI线程。永远不要在UI中调用它。请改用Dispatcher。或者声明btn_单击async并调用wait Task.delay100谢谢Clemens。等待任务。延迟100完成任务。但是如果Thread.Sleep100是windowB标签没有更新的原因,那么这是否意味着如果我删除了那行代码,那么一切都会按预期工作?@nammae:没有,因为循环仍然在UI线程上执行。您需要在另一个线程上睡眠/暂停。