Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF从同一线程中的另一个窗口更新窗口的UI控件_Wpf_Multithreading - Fatal编程技术网

WPF从同一线程中的另一个窗口更新窗口的UI控件

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.

假设我分别定义了两个名为WindowA和WindowB的窗口

WindowA有一个名为btn的按钮

WindowB有一个名为processLbl的标签

当用户单击WindowA中的按钮时,将显示WindowB并执行一些逻辑

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线程上执行。您需要在另一个线程上睡眠/暂停。