UI未使用MVVM更新PropertyChanged

时间:2013-10-30 13:16:39

标签: wpf inotifypropertychanged updating

虽然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

...然后边框变得可见。

这怎么可能?

3 个答案:

答案 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的情况也是如此:公共财产可见性为可见性