Popup不会打开

时间:2016-10-29 12:55:35

标签: c# wpf

我有一个看似简单的问题:一个导致我麻烦的弹出窗口在精简版本中看起来像这样(完整版本在Border元素中有一个微调器UserControl,但奇怪的行为是相同的或没有)。 XAML是这样的:

<Popup Name="PleaseWaitPopup" Placement="Center" IsOpen="False" StaysOpen="True" Opened="PopupOpened" Closed="PopupClosed">
    <Border Width="200" Height="200" Padding="20" Background="#222">
        <StackPanel Orientation="Vertical">
            <TextBlock Name="WaitHeadTxt" Margin="0 0 0 36" Style="{StaticResource PopupHeadStyle}" VerticalAlignment="Top" FontSize="16"></TextBlock>
            <Border Width="60" Height="60">
            </Border>
        </StackPanel>
    </Border>
</Popup>

所有元素(PopupOpened(),PopupClosed(),PopupHeadStyle)都经过了良好的测试,可以在同一个项目中的许多其他弹出窗口中正常工作。

为了响应用户操作,我想在启动需要几秒钟才能完成的事情之前打开此弹出窗口(尝试通过WiFi连接设备)。代码又简单了:

PleaseWaitPopup.IsOpen = true;
try
{
    wifiDeviceProvider = new PtpIpProvider();
    DeviceManager.AddDevice(wifiDeviceProvider.Connect("192.168.1.1"));
}
catch (Exception ex)
{
...
}

在我的测试用例中,我没有连接外部设备,因此WiFi连接尝试在10秒后返回超时。弹出窗口始终只在超时后打开,这是我没有得到的。此时没有其他弹出窗口打开。

我尝试使用其他操作代码(FTP传输而不是WiFi连接) - 问题仍然存在,因此WiFi连接代码不太可能与此有关。尝试通过打开弹出窗口或WiFi连接或两者来实现异步,通过&#34; this.Dispatcher.Invoke(()=&gt; {...});&#34; ,但这没有任何区别。

我在这里缺少什么想法?一定是傻事,但我似乎无法弄明白。谢谢!

1 个答案:

答案 0 :(得分:0)

您的WiFi代码在有机会更新UI之前看起来阻止了UI线程。所以它一旦从那里返回就会更新(即超时)。

作为一种基本的解决方法,您可以使用以下内容:

PleaseWaitPopup.IsOpen = true;

Task.Run(() =>
{
    try
    {
        wifiDeviceProvider = new PtpIpProvider();
        DeviceManager.AddDevice(wifiDeviceProvider.Connect("192.168.1.1"));
    }
    catch (Exception ex)
    {
        ...
    }
});

请注意,catch块不在UI线程上,因此不要尝试更新其中的UI而不要定位UI线程。还要注意,任务将立即返回到该代码中 - 如果您想等待任务,则需要进行一些更改。

理想情况下,你想要完全异步。我建议阅读Stephen Cleary的文章,了解有关异步最佳实践的更多信息。例如Async/Await - Best Practices in Asynchronous Programming