WPF - 防止绑定在加载数据时更新

时间:2015-11-18 18:45:43

标签: c# wpf mvvm

目前,对于我正在开发的应用程序,我在视图中隐藏了一个父容器,并在加载过程中显示了一个加载动画 - 更新UI似乎很难(并且很难挂起)数据绑定控件在更新时可见。

理想情况下,我希望能够禁用父容器,降低其不透明度并将加载动画覆盖在顶部 - 但保持父容器可见加载前的方式 。加载完成后,我希望允许数据绑定控件更新。

我没有幸运地追踪到这个问题的解决方案......我能找到的最接近的是可以在绑定上设置的delay属性,但很明显在这种情况下,这不是很有用。

我的viewmodel中有一个布尔IsLoading属性,我想推动它。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

有一种方法可以显式控制何时更新双向绑定的(使用UpdateSourceTrigger="Explicit"),但我不认为你可以控制何时目标已更新。

最简单的选择可能是在您加载数据时清除容器的DataContext,并在完成后将其设置回来。

答案 1 :(得分:0)

我通常以这种方式解决这类问题。假设您的ViewModel表示类型为Dog的对象,因此您的ViewModel可能名为DogViewModelDogVM(我更喜欢后者,除非我正在编写软件来管理虚拟机,但我离题了)。所以让我们说这个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#中则不那么繁琐。