目前,对于我正在开发的应用程序,我在视图中隐藏了一个父容器,并在加载过程中显示了一个加载动画 - 更新UI似乎很难(并且很难挂起)数据绑定控件在更新时可见。
理想情况下,我希望能够禁用父容器,降低其不透明度并将加载动画覆盖在顶部 - 但保持父容器可见加载前的方式 。加载完成后,我希望允许数据绑定控件更新。
我没有幸运地追踪到这个问题的解决方案......我能找到的最接近的是可以在绑定上设置的delay
属性,但很明显在这种情况下,这不是很有用。
我的viewmodel中有一个布尔IsLoading
属性,我想推动它。
有什么建议吗?
答案 0 :(得分:0)
有一种方法可以显式控制何时更新双向绑定的源(使用UpdateSourceTrigger="Explicit"
),但我不认为你可以控制何时目标已更新。
最简单的选择可能是在您加载数据时清除容器的DataContext
,并在完成后将其设置回来。
答案 1 :(得分:0)
我通常以这种方式解决这类问题。假设您的ViewModel表示类型为Dog
的对象,因此您的ViewModel可能名为DogViewModel
或DogVM
(我更喜欢后者,除非我正在编写软件来管理虚拟机,但我离题了)。所以让我们说这个DogVM
类看起来像这样:
public sealed class DogVM : INotifyPropertyChanged // because bindings, yeah?
{
public string Name { /* stuff here */ }
public string Breed { /* stuff here */ }
public string Coat { /* stuff here */ }
public DateTime BornOn { /* stuff here */ }
public bool IsLoading { /* stuff here */ }
// other stuff as well, like INotifyPropertyChanged implementation
}
如果您的虚拟机看起来像这样,那么您所拥有的就是混合的问题。您有两个问题:加载数据(并以可绑定的方式反映该状态),并以可绑定的方式使您的模型适应您的视图。
我建议将此代码分为两类。一个用于处理加载状态,另一个用于处理Dog
类的显示详细信息。例如:
public sealed class DogLoaderVM : INotifyPropertyChanged
{
public DogVM Dog { /* stuff here */ }
public bool IsLoading { /* stuff here */ }
// other stuff here
}
public sealed class DogVM : INotifyPropertyChanged
{
public string Name { /* stuff here */ }
public string Breed { /* stuff here */ }
public string Coat { /* stuff here */ }
public DateTime BornOn { /* stuff here */ }
// other stuff here
}
然后,对于任何给定的绑定,原来是这样的:
<TextBlock Text="{Binding Name}" />
您将其更新为:
<TextBlock Text="{Binding Dog.Name}" />
使用此模式,您有几个选择。您可以将Dog
属性保留在DogLoaderVM
中,其值为null
,直到加载为止,然后直接处理XAML中缺少值(例如,通过TargetNullValue
)。
然而,如果这太复杂并且在你的XAML中需要肮脏,丑陋,讨厌的东西(当然,这是处理XAML时的相对术语),你可以从DogVM
中提取一个接口,并使用null object pattern对负载仍未处理时绑定到视图的数据进行细粒度控制。例如,有些人喜欢将“(加载......)”放入UI中,而加载处于挂起状态,并且在XAML中可能会变得非常麻烦和冗余,而在C#中则不那么繁琐。