使用棱镜创建基本加载视图

时间:2013-10-07 07:29:08

标签: c# mvvm asynchronous prism

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

我创建了一个基本视图来实现这种行为(即具有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;
            }
        }
    }
}

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进行绑定

1 个答案:

答案 0 :(得分:1)

这是一个非常复杂的主题。

我建议稍微改变一下方法 - 而不是将IsBusy属性放在基本视图模型中,而是将其设为抽象,以便每个派生的视图模型都必须实现自己的特定检查。

public class BaseViewModel : INotifyPropertyChanged
{

    public abstract bool IsBusy { get; }

}

public class FancyViewModel : BaseViewModel
{

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

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

或者不使用计数器,您可以使用线程安全CountdownEvent class。如果你想要真正先进,那么你可以查看System.Threading namespace中的各种线程信令机制,或者查看task parallelismTask object