标签在第二个窗口后未显示

本文关键字:显示 窗口 第二个 标签 | 更新日期: 2023-09-27 18:31:02

我正在修复一个已经存在的应用程序,但我遇到了一些奇怪的问题。

在 GUI 的某些部分,我们的操作需要一些时间。因此,我们创建了一个名为 Wait 的小窗口,其中包含一个简单的消息Please wait...。我们只需在需要时Show/Hide窗口。

但问题来了。第二次显示窗口时,不显示Please wait... Label

Wait.xaml:

<Window x:Class="WpfApplication1.Wait"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Wait" SizeToContent="WidthAndHeight">
    <StackPanel>
        <Label>Please wait...</Label>
    </StackPanel>
</Window>

等待.xaml.cs

public partial class Wait : Window
{
    public Wait()
    {
        InitializeComponent();
    }
}

最后,我只是在最小的WPF应用程序中尝试一下:

// The window is shown perfectly
m_WaitWindow.Show();
Thread.Sleep(5000);
m_WaitWindow.Hide();
Thread.Sleep(2000);
// The label is not shown, the window is empty
m_WaitWindow.Show();
Thread.Sleep(5000);
m_WaitWindow.Hide();

我不知道如何解决这个问题,我尝试了很多事情,比如UpdateLayout Show后都没有效果。

不仅仅是关于如何解决这个问题的答案,我会理解为什么会发生这种情况?

标签在第二个窗口后未显示

正如 Hans Passant 发布的那样,您应该在 UI 线程以外的单独线程上执行长时间运行的工作。 如果你真的坚持在主线程上这样做,那么通常的做法是调用类似 Application.DoEvents() 的东西。 此调用在 WPF 中不存在,因为它是一种黑客攻击,表明您在 UI 线程上做了太多工作。 但是,如果您真的必须尝试完成此操作,则可以在第二次显示窗口后立即添加此行:

Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));

它本质上与Application.DoEvents()相同,只是有一些小怪癖。 但是,更好的解决方案是启动一个BackgroundWorker来执行长时间运行的过程,同时 UI 保持活动状态。 更多信息在这里。

正如Hans Passant所说,你正在阻止UI线程。 (不打算像苏斯博士那样回答...

通过在后台线程中进行等待/繁重的工作,这很容易解决。 您的最终实现可能会因您使用的 .NET 和 Visual Studio 版本而异,但您可以通过以下简单示例完成您所追求的目标:

// The window is shown perfectly.
m_WaitWindow.Show();
ThreadPool.QueueUserWorkItem(arg =>
    {
        Thread.Sleep(5000);
        Dispatcher.BeginInvoke(new Action(() => m_WaitWindow.Hide()));
        Thread.Sleep(2000);
        // The window is still shown perfectly, because the UI thread is not being blocked.
        Dispatcher.BeginInvoke(new Action(() => m_WaitWindow.Show()));
        Thread.Sleep(5000);
        Dispatcher.BeginInvoke(new Action(() => m_WaitWindow.Hide()));
    }, null);

注意:在原始情况下,您还应该看到弹出窗口对用户交互没有响应 - 这是一个好兆头,表明您已经阻止了 UI 线程。