3

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

在我们的 GUI 的某些部分,我们的操作需要一些时间。所以我们创建了一个小窗口,里面Wait有一条简单的消息Please wait...。我们只是Show/Hide在需要时打开窗口。

但问题就在这里。我们第二次显示窗口时,Please wait... Label不显示 in。

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>

Wait.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但没有效果。

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

4

2 回答 2

1

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

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

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

于 2013-09-12T16:43:41.980 回答
0

正如 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 线程的好兆头。

于 2013-09-12T18:09:54.513 回答