如何在WPF中的异步操作期间阻止UI界面

4
我们有一个 WPF 应用程序(实际上是一个 VSTO WPF 应用程序)。在某些控件上,有多个元素,当单击它们时,会从 Web 服务加载数据并更新 UI。现在,我们同步执行这些 Web 请求,阻塞 UI 线程,直到响应返回。这会阻止用户在数据加载时点击应用程序的其他部分,可能使应用程序处于无效状态以处理返回的数据。
当然,如果请求时间很长,应用程序就会变得无响应。理想情况下,在此期间我们希望取消按钮处于活动状态,但除此之外没有其他控件处于活动状态。是否有巧妙的方法可以做到这一点,或者我们必须切换请求以使用 BackgroundWorker 异步执行,并编写一些内容,在请求进行时禁用除了取消按钮以外的所有控件?
编辑:对于我们已经预计需要长时间运行的操作(如下载文件等),我们会弹出进度对话框窗口。案例在于当您预计的操作速度相当快(最多几秒钟),但偶尔需要更长时间时。在这种情况下,短暂地弹出整个窗口会分散注意力。
5个回答

4

您的可点击控件应该绑定到命令,当后台任务正在进行时,命令应该返回CanBeExecuted false。如果这样做,绑定到这些命令的控件将自动禁用和启用。

您可以通过创建一个实现后台任务进行检查的命令类来避免重复大量代码,然后从该类派生所有命令(当然除了取消命令)。


1

Silverlight Toolkit 包含一个 BusyIndicator 控件。该工具包是开源的,因此您可能很容易将其移植到 WPF。

当将其 IsBusy 属性设置为 true 时(无论是在代码中还是通过将其绑定到模型),它会禁用并使其所分配的区域中的所有内容变灰。使用方法如下:

<ctl:BusyIndicator>
    <StackPanel x:Name="myDataArea">
        <Button Content="Load Data" />
        <DataGrid x:Name="myDataGrid" />
    </StackPanel>
</ctl:BusyIndicator>

1

当你在单独的线程上进行异步请求时,显示一个带有取消按钮(以及进度条或其他活动指示器)的模态对话框。

这样用户就无法与底层UI进行交互,他们仍然可以得到反馈,知道某些事情正在发生……并且有取消它的能力。


1
一种方法是在等待响应时将半透明画布覆盖在 UI 的不可访问部分上,并在中心放置一个带有取消按钮的消息。

取消按钮在请求开始之前已经可见,但我想我们可以给它一个更高的 z-index。 - mcintyre321
可以将多个按钮绑定到同一个命令。 - Doug Ferguson
当然 - 我只是在思考如何在不创建两个完全相同的取消按钮的情况下完成它,其中一个放置在另一个上面。 - mcintyre321

0

除了“取消”以外,我想不到其他简单的方法来禁用所有控件。

话虽如此,如果您显示了一个带有“取消”按钮的“工作中”或进度对话框,可能会给用户提供更好的体验。

您可以使用此对话框显示有关Web请求进度和任何错误消息的有用信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接