2

我的 prism 应用程序有很多从我的视图模型中调用的异步操作。在某些情况下,我希望禁用视图并显示某种忙碌指示符,直到视图模型从异步操作中取回结果。

我虽然创建了一个将实现此行为的基本视图(即具有 IsLoading 的依赖属性,它将禁用该视图并在其上方显示一个忙碌指示符)。问题是,我不确定如何实现这个基本视图。任何帮助将不胜感激,谢谢。

编辑:我认为我写了一个 LoadingView 来完成这项工作。

public class LoadingView : UserControl { private object content;

    public bool IsLoading
    {
        get
        {
            return (bool)GetValue(IsLoadingProperty);
        }
        set
        {
            SetValue(IsLoadingProperty, value);
        }
    }

    private ProgressRing m_RingControl;

    public LoadingView()
    {
        m_RingControl = new ProgressRing();
        m_RingControl.IsActive = false;
    }

    // Using a DependencyProperty as the backing store for IsLoading.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsLoadingProperty =
        DependencyProperty.Register("IsLoading", typeof(bool), typeof(LoadingView), new PropertyMetadata(false, IsActivePropertyChanged));

    private static void IsActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        LoadingView view = d as LoadingView;
        if (view != null)
        {
            // Loading - show ring control
            if (((bool)e.NewValue) == true)
            {
                view.content = view.Content;
                view.Content = view.m_RingControl;
                view.m_RingControl.IsActive = true;
            }
            else
            {
                view.m_RingControl.IsActive = false;
                view.Content = view.content;
            }
        }
    }
}

我在视图模型中使用一些 IsLoading(或 IsBusy)绑定 LoadingView.IsLoading

4

1 回答 1

2

这是一个可以很快变得非常复杂的主题。

我建议在方法上做一点小改动——不要将 IsBusy 属性放在基本视图模型中,而是将其抽象化,以便每个派生的视图模型都必须实现自己的特定检查。

public class BaseViewModel : INotifyPropertyChanged
{

    public abstract bool IsBusy { get; }

}

public class FancyViewModel : BaseViewModel
{

    public override bool IsBusy
    {
        get { return [check #1] && [check #2]...; }
    }
}

现在由每个特定的视图模型来确定它是否忙。一个粗略的机制是有一个计数器,每次启动异步函数时递增,并在操作结束时递减 - 如果它的值等于 0,则没有当前的异步操作。使用标志或计数器时,请注意由于编译器优化而可能发生的各种属性读取问题,学习在正确的位置使用 volatile 关键字。

或者,您可以使用线程安全的CountdownEvent 类,而不是保留一个计数器。如果您想获得真正的高级,那么您可以查看System.Threading 命名空间中的各种线程信号机制,或者查看任务并行性Task 对象

于 2013-10-07T08:19:29.237 回答