虽然UI组件的可见性绑定到ViewModel属性并且该属性的PropertyChanged已实现,但UI是否有可能跳过更新自身?
查看/ XAML:
<Border Visibility="{Binding ShowLoadingPanel, Converter={StaticResource BoolToHiddenConverter}}">
<TextBlock Text="LOADING..." />
</Border>
ViewModel:
Public Property ShowLoadingPanel As Boolean
Get
Return _showLoadingPanel
End Get
Set(value As Boolean)
_showLoadingPanel = value
OnPropertyChanged("ShowLoadingPanel")
End Set
End Property
从ViewModel运行以下内容时:
ShowLoadingPanel = True
RunBigTask() 'runs a task that takes a long time
ShowLoadingPanel = False
... XAML中定义的边框不可见。
但是,如果我添加需要用户交互的内容,例如:
ShowLoadingPanel = True
MsgBox("Click to continue")
RunBigTask() 'runs a task that takes a long time
ShowLoadingPanel = False
...然后边框变得可见。
这怎么可能?
答案 0 :(得分:4)
你应该在后台线程中运行长时间运行的任务,因为它阻止你的UI线程更新Visibility
......实际上,Visibility
应该当长时间运行的任务完成时更新。
用户使用BackgroundWorker
对象来执行此操作是很常见的。您可以在MSDN上的BackgroundWorker
Class页面上找到完整的工作示例。
BackgroundWorker
的常见替代方法是使用Task
对象异步运行长时间运行的进程。您可以在MSDN上的Task
Class页面上找到使用Task
的完整工作示例。
答案 1 :(得分:2)
您正在阻止Dispatcher,阻止更新布局。当您打开一个消息框时,您推送一个嵌套的消息循环,允许Dispatcher继续处理其队列,直到消息框关闭。布局更新在此期间发生。
当您在常规窗口上调用ShowDialog()
时会发生同样的事情:您的代码会阻塞,但Dispatcher会继续运行,因此UI会按预期更新。在弹出嵌套的消息循环之前,您的代码不会恢复,这会在您关闭模式对话框(如消息框)时自动发生。
答案 2 :(得分:0)
我正在使用C#,在我们的例子中,Visiblity不是布尔值,而是枚举:System.Windows.Visibility,其值为Hidden / Visible / Collapsed。
VB的情况也是如此:公共财产可见性为可见性